Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/***
*util.c - utilities for fp transcendentals * * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved. * *Purpose: * _set_exp and _add_exp are as those defined in Cody & Waite * *Revision History: * 08-15-91 GDP written * 10-20-91 GDP removed _rint, unsafe_intrnd * 02-05-92 GDP added _fpclass * 03-27-92 GDP added _d_min * 06-23-92 GDP added _d_mzero * *******************************************************************************/ #include "trans.h"
/* define special values */
_dbl _d_inf = {SET_DBL (0x7ff00000, 0x0) }; //positive infinity
_dbl _d_ind = {SET_DBL (D_IND_HI, D_IND_LO)}; //real indefinite
_dbl _d_max = {SET_DBL (0x7fefffff, 0xffffffff)}; //max double
_dbl _d_min = {SET_DBL (0x00100000, 0x00000000)}; //min normalized double
_dbl _d_mzero = {SET_DBL (0x80000000, 0x00000000)}; //negative zero
double _set_exp(double x, int exp) /* does not check validity of exp */ { double retval; int biased_exp; retval = x; biased_exp = exp + D_BIASM1; *D_EXP(retval) = (unsigned short) (*D_EXP(x) & 0x800f | (biased_exp << 4)); return retval; }
int _get_exp(double x) { signed short exp; exp = (signed short)((*D_EXP(x) & 0x7ff0) >> 4); exp -= D_BIASM1; //unbias
return (int) exp; }
double _add_exp(double x, int exp) { return _set_exp(x, INTEXP(x)+exp); }
double _set_bexp(double x, int bexp) /* does not check validity of bexp */ { double retval; retval = x; *D_EXP(retval) = (unsigned short) (*D_EXP(x) & 0x800f | (bexp << 4)); return retval; }
int _sptype(double x) { if (IS_D_INF(x)) return T_PINF; if (IS_D_MINF(x)) return T_NINF; if (IS_D_QNAN(x)) return T_QNAN; if (IS_D_SNAN(x)) return T_SNAN; return 0; }
/***
*double _decomp(double x, double *expptr) * *Purpose: * decompose a number to a normalized mantisa and exponent * *Entry: * *Exit: * *Exceptions: * *******************************************************************************/
double _decomp(double x, int *pexp) { int exp; double man;
if (x == 0) { man = 0; exp = 0; } else if (IS_D_DENORM(x)) { int neg;
exp = 1-D_BIASM1; neg = x < 0.0; while((*D_EXP(x) & 0x0010) == 0) { /* shift mantissa to the left until bit 52 is 1 */ (*D_HI(x)) <<= 1; if (*D_LO(x) & 0x80000000) (*D_HI(x)) |= 0x1; (*D_LO(x)) <<= 1; exp--; } (*D_EXP(x)) &= 0xffef; /* clear bit 52 */ if (neg) { (*D_EXP(x)) |= 0x8000; /* set sign bit */ } man = _set_exp(x,0); } else { man = _set_exp(x,0); exp = INTEXP(x); }
*pexp = exp; return man; }
|