Пример #1
0
/* _IEEE_EXPONENT_I6_R - IEEE EXPONENT returns the exponent part of the
 *                      64-bit argument in 46-bit integer.
 */
_f_int6
_IEEE_EXPONENT_I6_R(_f_real8 x)
{
	int		i;
	REGISTER_8	s1, s2;

	/* if x is a NaN, return HUGE */
	if (isnan64(x))
		return HUGE_INT6_F90;
	s1.f = x;

	/* clear sign bit */
	s1.ui &= ~IEEE_64_SIGN_BIT;

	/* if x is + or - infinity, return HUGE */
	if (s1.ui == IEEE_64_INFINITY)
		return HUGE_INT6_F90;

	/* if x is zero, return -HUGE */
	if (x == 0.0e0)
		return -HUGE_INT6_F90;

	/* shift exponent bits to right. */
	s1.ui >>= IEEE_64_MANT_BITS;
	if (s1.ui == 0) {

		/* x is a subnormal number (implicit leading bit is zero
		 * and the exponent is zero).  Calculate the exponent
		 * based on normalized x.
	 	 *
		 * get mantissa
		 */
		s2.f = x;
		s2.ui = IEEE_64_MANTISSA & s2.ui;

		/* get leading zeros in mantissa part. */
		i = _leadz8(s2.ui) - IEEE_64_EXPO_BITS;

		/* calculate exponent. */
		s1.i -= (IEEE_64_EXPO_BIAS + i);
	} else {
		/* subtract exponent bias. */
		s1.i -= (IEEE_64_EXPO_BIAS);
	}
	return (_f_int6) s1.i;
}
Пример #2
0
inline static		/* for the inline version of this function. */
#endif
_f_real8
_FRACTION(_f_real8 x)
{
	int             lz;
	REGISTER_8      s1, sign_bit, mantissa, exponent;
	if (x == 0.0)
		return 0.0;
	/* if x is either infinity or a NaN, return a Nan */
	if (x == IEEE_64_INFINITY)
		return	_SGL_NaN;
	if (isnan64(x))
		return	x;
	s1.f = x;

	/* get sign bit. */
	sign_bit.ui = IEEE_64_SIGN_BIT & s1.ui;

	/* get mantissa. */
	mantissa.ui = IEEE_64_MANTISSA & s1.ui;

	/* get exponent. */
	exponent.ui = IEEE_64_EXPONENT & s1.ui;
	if (exponent.ui == LL_CONST(0x0)) {

		/* 1. number is subnormal.  normalize mantissa.
		 * Get leading zeros of mantissa.
		 */
		lz = _leadz8(mantissa.ui) - IEEE_64_EXPO_BITS;

		/* 2. normalize by shifting out all leading zeros
		 *    and first 1 bit.
		 */
		mantissa.ui = (mantissa.ui << lz) & IEEE_64_MANTISSA;
	}

	/* position exponent bias less the implicit bit. */
	exponent.ui = IEEE_64_EXPO_BIAS - 1;
	exponent.ui = exponent.ui << IEEE_64_MANT_BITS;

	/* extract fraction. */
	s1.ui = exponent.ui | mantissa.ui | sign_bit.ui;
	return s1.f;
}
Пример #3
0
inline static           /* for the inline version of this function. */
#endif

#define MIN(a,b)        ((a) < (b) ? (a) : (b))

/***  Algorithm for f90 FRACTION
 * FRACTION - return the fractional part of the 128-bit model
 * 		representation of the argument value.
 **/

_f_real16
_FRACTION_16(_f_real16 x)
{
	int	lz, ileadzcnt, loopn;
#if defined(_WORD32)
	union ldble_float {
		_f_real16		whole;
		unsigned long long	ui[1];
	} f, result, mantissa;
	unsigned long long	sign_bit, exponent;
#else
	union ldble_float {
		_f_real16		whole;
		unsigned long           ui[1];
	} f, result;
	unsigned long		sign_bit, exponent;
#endif

	static int word_size =	64;

        if (x == 0.0)
                return 0.0;
	f.whole =	x;
	/* if x is either infinity or a NaN, return a Nan */
	if ((f.ui[0] == IEEE_128_64_EXPO) && (f.ui[1] == 0))
			return	_DBL_NaN;
	if (isnan128(x))
		return	x;

        /* get sign bit. */
        sign_bit =	IEEE_128_64_SIGN_BIT & f.ui[0];

	/* Get the absolute value of x by ANDing the upper half
	 * with the NOT of 0x8000000000000000 (the sign bit mask).
	 */
	f.ui[0] &= ~IEEE_128_64_SIGN_BIT;

        /* get exponent. */
	exponent =	f.ui[0] & IEEE_128_64_EXPO;

        /* get mantissa and zero out exponent portion */
	f.ui[0] &= IEEE_128_64_MANT1;

	result.whole =	f.whole;
	if (exponent == LL_CONST(0x0)) {

		/* 1. Number is subnormal.  Normalize mantissa and
		 * get leading zeros in mantissa
		 */
		lz =	0;
		for (loopn = 0; loopn < 2; loopn++) {
			ileadzcnt = _leadz8(f.ui[loopn]);
			lz += ileadzcnt;
			if (ileadzcnt < word_size)
				break;
		}
		lz = lz - IEEE_128_EXPO_BITS;

		/* 2. Normalize by shifting out all leading zeros
		 *    and first 1 bit.
		 * Determine number of mantissa bits in first 64 bits
		 * of the mantissa plus the implicit bit.
		 */
		ileadzcnt =	word_size - IEEE_128_EXPO_BITS;

		if (lz >= ileadzcnt) {

			/* The first 48 bits of the mantissa are zero. */
			result.ui[0] = (f.ui[1] << (lz - ileadzcnt)) >>
				IEEE_128_EXPO_BITS;
			result.ui[1] = f.ui[1] << (MIN(word_size,lz));
		} else {
Пример #4
0
/* _IEEE_EXPONENT_I6_D - IEEE EXPONENT returns the exponent part of the
 *                       128-bit argument in 46-bit integer.
 */
_f_int6
_IEEE_EXPONENT_I6_D(_f_real16 x)
{
	int		i, ileadzcnt, loopn;
#if defined(_WORD32)
	union ldble_float {
		_f_real16		whole;
		unsigned long long	ui[2];
		long long		si[2];
	} f, result;
#else
	union ldble_float {
		_f_real16		whole;
		unsigned long		ui[2];
		long			si[2];
	} f, result;
#endif

	static int word_size =	64;

	/* if x is a NaN, return a HUGE */
	if (isnan128(x))
		return HUGE_INT6_F90;
	f.whole =	x;

	/* Get the absolute value of x by ANDing the upper half
	 * with the NOT of 0x8000000000000000 (the sign bit mask).
	 */
	f.ui[0] &= ~IEEE_128_64_SIGN_BIT;

	/* if x is + or -infinity, return a HUGE */
	if ((f.ui[0] == IEEE_128_64_EXPO) && (f.ui[1] == 0))
		return HUGE_INT6_F90;

	/* if x is zero, return -HUGE */
	if (x == 0.0e0)
		return -HUGE_INT6_F90;

	/* Separate the exponent from the 128-bit float value and
	 * right justify it.
	 */
	result.ui[0] = f.ui[0] >> (IEEE_128_MANT_BITS - word_size);
	if (result.ui[0] == 0) {

		/* x is a subnormal number (implicit leading bit is zero
		 * and the exponent is zero).  Calculate the exponent
		 * based on normalized x.
		 *
		 * get mantissa
		 */
		f.ui[0] &= IEEE_128_64_MANT1;
		i = 0;

		/* get leading zeros in mantissa part */
		for (loopn = 0; loopn < 2; loopn++) {
			ileadzcnt = _leadz8(f.ui[loopn]);
			i += ileadzcnt;
			if (ileadzcnt < word_size)
				break;
		}
		i = i - IEEE_128_EXPO_BITS;

		/* calculate exponent. */
		result.si[0] -= (IEEE_128_EXPO_BIAS + i);
	} else {
		/* subtract exponent bias. */
		result.si[0] -= (IEEE_128_EXPO_BIAS);
	}
	return (_f_int6) result.si[0];
}
Пример #5
0
/* _IEEE_EXPONENT_I2_D - IEEE EXPONENT returns the exponent part of the
 *                      128-bit argument in 16-bit integer.
 */
_f_int2
_IEEE_EXPONENT_I2_D(_f_real16 x)
{
	union _ieee_ldouble {
		_f_real16	ldword;
		_f_real8	dbword[2];
	};
#if __BYTE_ORDER == __LITTLE_ENDIAN
        const int dbword_hi = 1;
        const int dbword_lo = 0;
#else
        const int dbword_hi = 0;
        const int dbword_lo = 1;
#endif
	union _ieee_double {
		_f_real8		dword;
		_f_int8			lword;
		unsigned long long	ull;
		struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
			unsigned int mantissa2	: IEEE_64_MANT_BTS2;
			unsigned int mantissa1	: IEEE_64_MANT_BTS1;
			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 mantissa1	: IEEE_64_MANT_BTS1;
			unsigned int mantissa2	: IEEE_64_MANT_BTS2;
#endif
		} parts;
	};
	_f_int2	iresult = 0;

	switch(fp_class_l(x)) {
		case FP_SNAN:
		case FP_QNAN:
		case FP_POS_INF:
		case FP_NEG_INF:
			{
			/* return positive huge for NaN or infinity. */
			return(HUGE_INT2_F90);
			}
		case FP_POS_NORM:
		case FP_NEG_NORM:
			{
#pragma weak	logbl
			return((_f_int2) logbl(x));
			}
		case FP_POS_DENORM:
		case FP_NEG_DENORM:
			{
			/* return exponent from first 64-bit double. */
			union _ieee_ldouble x_val;
			x_val.ldword	= x;
			switch(fp_class_d(x_val.dbword[dbword_hi])) {
				case FP_POS_NORM:
				case FP_NEG_NORM:
					{
					union _ieee_double db_x;
					db_x.dword	= x_val.dbword[dbword_hi];
					return((_f_int2)(db_x.parts.exponent -
					  IEEE_64_EXPO_BIAS));
					}
				case FP_POS_DENORM:
				case FP_NEG_DENORM:
					{
					union _ieee_double db_x;
					db_x.dword	= x_val.dbword[dbword_hi];
					db_x.ull	=
					  IEEE_64_MANTISSA & db_x.ull;
					return((_f_int2)(-IEEE_64_EXPO_BIAS -
					  (_leadz8(db_x.ull) +
					  IEEE_64_EXPO_BITS)));
					}
				}
			}
		case FP_POS_ZERO:
		case FP_NEG_ZERO:
			{
			/* return negative huge for zero. */
			return(-HUGE_INT2_F90);
			}
	}
	return(iresult);
}
Пример #6
0
/* _IEEE_EXPONENT_I2_R - IEEE EXPONENT returns the exponent part of the
 *                      64-bit argument in 16-bit integer.
 */
_f_int2
_IEEE_EXPONENT_I2_R(_f_real8 x)
{
	union _ieee_double {
		_f_real8		dword;
		_f_int8			lword;
		unsigned long long	ull;
		struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
			unsigned int mantissa2	: IEEE_64_MANT_BTS2;
			unsigned int mantissa1	: IEEE_64_MANT_BTS1;
			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 mantissa1	: IEEE_64_MANT_BTS1;
			unsigned int mantissa2	: IEEE_64_MANT_BTS2;
#endif
		} parts;
	};
	_f_int2	iresult = 0;

	switch(fp_class_d(x)) {
		case FP_SNAN:
		case FP_QNAN:
		case FP_POS_INF:
		case FP_NEG_INF:
			{
			/* return positive huge for NaN or infinity. */
			return(HUGE_INT2_F90);
			}
		case FP_POS_NORM:
		case FP_NEG_NORM:
			{
			union _ieee_double x_val;
			x_val.dword	= x;
			return((_f_int2)(x_val.parts.exponent -
				IEEE_64_EXPO_BIAS));
			}
		case FP_POS_DENORM:
		case FP_NEG_DENORM:
			{
			union _ieee_double x_val;
			x_val.dword	= x;
			x_val.ull	= IEEE_64_MANTISSA & x_val.ull;;

			/* _leadz returns number of zeros before first 1
			 * in mantissa.  Add 8 to exclude exponent bits,
			 * but count sign bit since implicit bit needs to
			 * be counted.
			 */
			return((_f_int2)(-IEEE_64_EXPO_BIAS -
				(_leadz8(x_val.ull) +
				IEEE_64_EXPO_BITS)));
			}
		case FP_POS_ZERO:
		case FP_NEG_ZERO:
			{
			/* return negative huge for zero. */
			return(-HUGE_INT2_F90);
			}
	}
	return(iresult);
}
Пример #7
0
_f_real8
_IEEE_BINARY_SCALE_I8(_f_real8 orig_number, _f_int8 orig_scale_factor)
{
	int	lz, lzm, shift;
	REGISTER_8	number, scale_factor, expon, exponent,
			orig_mantissa, mantissa, sign_bit;

	/* if x is a NaN, return a Nan */
	if (isnan64(orig_number))
		return orig_number;
	number.f =	orig_number;

	/* extract sign bit. */
	sign_bit.ui =	IEEE_64_SIGN_BIT & number.ui;

	/* extract exponent. */
	exponent.ui =	IEEE_64_EXPONENT & number.ui;

	/* extract mantissa. */
	orig_mantissa.ui = IEEE_64_MANTISSA & number.ui;

	/* if x is + or -infinity, return same infinity */
	number.ui &= ~IEEE_64_SIGN_BIT;
	if (number.ui == IEEE_64_INFINITY)
		return orig_number;

	/* if x is zero, return zero. */
	if (orig_number == 0)
		return orig_number;

	scale_factor.i =	orig_scale_factor;

	/* check for unnormalized number */
	if (exponent.ui == 0) {

		/* Denormmal.  Get leading zeros in original mantissa */
		lz =	_leadz8(orig_mantissa.ui);

		if (scale_factor.i > 0) {

			/* Scale number by a positive power of 2.  The
			 * result may need to be normalized.  Get
			 * leading zeros in mantissa = lzm.
			 */
			lzm = lz - IEEE_64_EXPO_BITS - 1;

			/* Any leading zeros in mantissa? */
			if (lzm > 0) {

				/* check if number of leading zeros in
				 * mantissa allows scaling by shifting.
				 */
				if (scale_factor.i <= lzm) {

					/* Enough lead zeros to shift.
					 * Exponent is unaffected.
					 */
					shift = scale_factor.i;
					expon.i = 0;
				} else {

					/* Scale by shifting what we can
					 * and adjust exponent for rest.
					 * The result is a normalized
					 * number.
					 */
					shift = lzm + 1;
					expon.i = scale_factor.i - lzm;
				}
			/* No leading zeros in mantissa. */
			} else {

				/* Shift by 1 to normalize mantissa. Do
				 * rest of scaling through exponent.
				 */
				shift =	1;
				expon.i = scale_factor.i;
			}
			/* position the exponent. */
			exponent.ui = expon.ui << IEEE_64_MANT_BITS;

			/* scale the mantissa. */
			mantissa.ui = orig_mantissa.ui << shift;

		/* Scale_factor LE 0. */
		} else {

			/* scale mantissa. */
			mantissa.ui = orig_mantissa.ui >> (-scale_factor.i);
			if ((-scale_factor.ui != 0) &&
			    (orig_mantissa.ui & (0x1 <<
			    (-scale_factor.i - 1)))) {
					mantissa.ui++;
			}

		}

		/* mask out any bits that may have shifted to the left of
		 * the mantissa area.
		 */
		mantissa.ui &= IEEE_64_MANTISSA;

		/* OR the new mantissa, the new exponent, and the original
		 * sign bit together to create the result.
		 */
		number.ui = mantissa.ui | exponent.ui | sign_bit.ui;

	} else {