BigReal &BigReal::multPow10(BRExpoType exp) { DEFINEMETHODNAME; if(!_isnormal()) { return *this; } int m = exp % LOG10_BIGREALBASE; BRExpoType n = exp / LOG10_BIGREALBASE; if(m == 0) { m_expo += n; m_low += n; if(m_expo > BIGREAL_MAXEXPO || m_expo < BIGREAL_MINEXPO) { throwBigRealInvalidArgumentException(method, _T("Invalid m_expo:%s"), format1000(m_expo).cstr()); } } else { if(m < 0) { m = -m; } const BRDigitType s = pow10(m); const BRDigitType t = BIGREALBASE / s; if(exp > 0) { // shift left Digit *p = m_first; Digit *q = p->next; // *this != 0 => p != NULL if(p->n >= t) { insertDigit(p->n / t); m_expo++; } while(q) { p->n = q->n/t + (p->n%t) * s; p = q; q = q->next; } p->n = (p->n%t) * s; } else { // exp < 0. shift right Digit *p = m_last; Digit *q = p->prev; // *this != 0 => p != NULL appendDigit((p->n % s) * t); m_low--; while(q) { p->n = p->n/s + (q->n%s) * t; p = q; q = q->prev; } p->n /= s; } m_expo += n; m_low += n; trimZeroes(); } return *this; }
ULONG BigReal::hashCode() const { if(!_isnormal()) { switch(m_low) { case BIGREAL_ZEROLOW: return 0; case BIGREAL_NANLOW : return 0xffffffff; case BIGREAL_INFLOW : return m_negative ? 0xfffffffe : 0xfffffffd; } } size_t s = m_expo; if(m_negative) s = ~s; for(const Digit *p = m_first; p; p = p->next) { s = s * 17 + p->n; } return sizetHash(s); }
double _IEEE_NEXT_AFTER_R_R(double x, double y) { /* Union defined to work with IEEE 64-bit floating point. */ union _ieee_double { double dword; long long lword; struct { #if defined(_LITTLE_ENDIAN) unsigned int mantissa : IEEE_64_MANT_BITS; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int sign : 1; #else unsigned int sign : 1; unsigned int exponent : IEEE_64_EXPO_BITS; unsigned int mantissa : IEEE_64_MANT_BITS; #endif } parts; }; int xfpclas = _fpclassify(x); int yfpclas = _fpclassify(y); if (xfpclas == FP_NAN) { return x; } else if (yfpclas == FP_NAN) { return y; } else if (xfpclas == FP_ZERO && yfpclas == FP_ZERO) { return x; } else if (x==y || xfpclas == FP_INFINITE) { return x; } else if (xfpclas == FP_ZERO) { union _ieee_double x_val; x_val.dword = DBL_MIN; x_val.parts.sign = x > y; /* return smallest normal number */ return(x_val.dword); } else { /* first argument is normal or denormal */ union _ieee_double x_val; int j; int resfpclas; x_val.dword = x; /* move one bit in the correct direction. ** Because of the way the implicit bit works, ** the exponent field is handled correctly. */ if (x > 0) { x_val.lword += (x>y) ? -1 : 1; } else { x_val.lword += (x>y) ? 1 : -1; } /* test for underflow or overflow */ if (_isnormal(x_val.dword)) return(x_val.dword); /* * Raise overflow exception for infinite result and * underflow exception for too small result. Raise * inexact exception for both cases. Allow subnormal * values to return without exception. */ resfpclas = _fpclassify(x_val.dword); if (resfpclas == FP_INFINITE) { j = FE_OVERFLOW; feraiseexcept(j); } else if (resfpclas == FP_ZERO) { j = FE_UNDERFLOW; feraiseexcept(j); } else { return(x_val.dword); } j = FE_INEXACT; feraiseexcept(j); return(x_val.dword); } }