Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
	}
}