Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

170 lines
3.4 KiB

/***
*utill.c - utilities for fp transcendentals
*
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
*
*Purpose:
* _set_expl and _add_expl 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-04-92 XY change to long double version
*
*******************************************************************************/
#include "transl.h"
#include "float.h"
/* define special values */
_ldbl _ld_inf = {0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //positive infinity
_ldbl _ld_ind = {0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //real indefinite
_ldbl _ld_max = {0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //max long double
_ldbl _ld_min = {0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //min normalized double
/***
*int _fpclassl(long double x) - floating point class
*
*Purpose:
* Compute the floating point class of a number, according
* to the recommendations of the IEEE std. 754
*
*Entry:
*
*Exit:
*
*Exceptions:
* This function is never exceptional, even when the argument is SNAN
*
*******************************************************************************/
int _fpclassl(long double x)
{
int sign;
if (IS_LD_SPECIAL(x)){
switch (_sptypel(x)) {
case T_PINF:
return _FPCLASS_PINF;
case T_NINF:
return _FPCLASS_NINF;
case T_QNAN:
return _FPCLASS_QNAN;
default: //T_SNAN
return _FPCLASS_SNAN;
}
}
sign = (*LD_EXP(x)) & 0x8000;
if (x == 0.0)
return sign? _FPCLASS_NZ : _FPCLASS_PZ;
if (IS_LD_DENORM(x))
return sign? _FPCLASS_ND : _FPCLASS_PD;
return sign? _FPCLASS_NN : _FPCLASS_PN;
}
long double _set_expl(long double x, int exp)
/* does not check validity of exp */
{
long double retval;
int biased_exp;
retval = x;
biased_exp = exp + LD_BIASM1;
*LD_EXP(retval) = (unsigned short) (*LD_EXP(x) & 0x8000 | biased_exp );
return retval;
}
int _get_expl(long double x)
{
signed short exp;
exp = (signed short)(*LD_EXP(x) & 0x7fff);
exp -= LD_BIASM1; //unbias
return (int) exp;
}
long double _add_expl(long double x, int exp)
{
return _set_expl(x, INTEXPL(x)+exp);
}
long double _set_bexpl(long double x, int bexp)
/* does not check validity of bexp */
{
long double retval;
retval = x;
*LD_EXP(retval) = (unsigned short) (*LD_EXP(x) & 0x8000 | bexp);
return retval;
}
int _sptypel(long double x)
{
if (IS_LD_INF(x))
return T_PINF;
if (IS_LD_MINF(x))
return T_NINF;
if (IS_LD_QNAN(x))
return T_QNAN;
if (IS_LD_SNAN(x))
return T_SNAN;
return 0;
}
/***
*long double _decompl(long double x, int *expptr)
*
*Purpose:
* decompose a number to a normalized mantisa and exponent
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
long double _decompl(long double x, int *pexp)
{
int exp;
long double man;
if (x == 0) {
man = 0;
exp = 0;
}
else if (IS_LD_DENORM(x)) {
exp = 1-LD_BIASM1;
while(*LD_HI(x) & 0x8000 == 0) {
/* shift mantissa to the left until bit 17 is 1 */
(*LD_HI(x)) <<= 1;
if (*LD_LO(x) & 0x80000000)
(*LD_HI(x)) |= 0x1;
(*LD_LO(x)) <<= 1;
exp--;
}
man = _set_expl(x,0);
}
else {
man = _set_expl(x,0);
exp = INTEXPL(x);
}
*pexp = exp;
return man;
}