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.
 
 
 
 
 
 

85 lines
3.1 KiB

unsigned int _uitrunc(double x) {
// _uitrunc converts the IEEE floating point long number x into a 32-bit
// unsigned int.
//
// The result is truncated towards zero, as in the Fortran INT function,
// regardless of the current rounding mode. If x > 2**32 or is
// +infinity, the result is 2**32.
// Be VERY CAREFUL when compiling this program with an optimizing compiler.
// The difference NaN-NaN is computed TWICE in order to cause an exception
// if the input is invalid. Smart compilers may recognize that x-x is 0.0
// and avoid generating the "fsub". No folding of floating point compu-
// tations should be done by the compiler!
unsigned answer;
volatile double NanMinusNan;
union {
double sum;
struct {
unsigned int lo;
unsigned int hi;
} ;
} xshifted;
// We are about to declare a magic number, *pf5243 == 2^52 + 2^43 in
// IEEE format. It needs to have bit 43 set because adding 2^52
// to a negative number could cause a borrow and in some
// weird cases (which I can't remember off the top of my head) the
// borrow could go all the way to the top of the fraction and thus cause
// the result to be shifted left by one bit, which messes up the lower
// 32 bits. To summarize: the 2^43 is added so that there will be a bit
// above bit 2^32 from which a subtract can always borrow. It could
// be any bit above 2^32.
//
// Positive numbers are not affected one way or the other by the 2^43
// bit.
const static unsigned int f5243[2] = {0x00000000, 0x43300800 };
const static double *pf5243 = (double *)f5243;
// fNAN == +NAN (Not A Number) in IEEE format
const static unsigned int fNAN[2] = { 0x00000000, 0x7ff00000 };
const static double *pfNAN = (double *)fNAN;
const static double LargestUnsignedInt = 4294967295.0;
const static double DoubleZero = 0.0;
// If x is NaN or is negative, set the bit for invalid IEEE exception.
// Because NanMinusNan is volatile the assignment will not removed by
// dead store elimination. The status is set as for a compare-ordered
// of x with zero, and the integer result is undefined (ie. FPCC and
// VXVC are set, and VXSNAN may be). I am not sure what this SHOULD do
// for the ill-defined cases; the above is a guess at what IEEE dictates,
// if anything (HSW 6/87).
if (( x != x ) || (x < DoubleZero)) {
NanMinusNan = *pfNAN - *pfNAN;
return(0);
}
// If x is too big, we can't convert it, either
if (x > LargestUnsignedInt) {
NanMinusNan = *pfNAN - *pfNAN;
return(0xffffffff);
}
else if (x == LargestUnsignedInt)
return(0xffffffff);
// Add the magic number; see the introductory note. The following
// mysterious comment appears in the original:
// 51 - 31 = 20, thus shift the integer part right by 20
xshifted.sum = x + *pf5243;
answer = xshifted.lo;
// If result was > x, it must have been rounded up. Correct by
// subtracting one.
if ((xshifted.sum - *pf5243) > x ) return answer - 1;
return answer;
}