/* @(#)s_lrint.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ /* * lrint(x) * Return x rounded to integral value according to the prevailing * rounding mode. * Method: * Using floating addition. * Exception: * Inexact flag raised if x not equal to lrint(x). */ #include "fdlibm.h" #ifndef _DOUBLE_IS_32BITS #ifdef __STDC__ static const double #else static double #endif /* Adding a double, x, to 2^52 will cause the result to be rounded based on the fractional part of x, according to the implementation's current rounding mode. 2^52 is the smallest double that can be represented using all 52 significant digits. */ TWO52[2]={ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ }; #ifdef __STDC__ long int lrint(double x) #else long int lrint(x) double x; #endif { __int32_t i0,j0,sx; __uint32_t i1; double t; volatile double w; long int result; EXTRACT_WORDS(i0,i1,x); sx = (i0>>31)&1; j0 = ((i0 & 0x7ff00000) >> 20) - 1023; if(j0 < 20) { if(j0 < -1) return 0; else { w = TWO52[sx] + x; t = w - TWO52[sx]; GET_HIGH_WORD(i0, t); j0 = ((i0 & 0x7ff00000) >> 20) - 1023; i0 &= 0x000fffff; i0 |= 0x00100000; result = i0 >> (20 - j0); } } else if (j0 < (8 * sizeof (long int)) - 1) { if (j0 >= 52) result = ((long int) i0 << (j0 - 20)) | (i1 << (j0 - 52)); else { w = TWO52[sx] + x; t = w - TWO52[sx]; EXTRACT_WORDS (i0, i1, t); j0 = ((i0 & 0x7ff00000) >> 20) - 1023; i0 &= 0x000fffff; i0 |= 0x00100000; result = ((long int) i0 << (j0 - 20)) | (i1 >> (52 - j0)); } } else { return (long int) x; } return sx ? -result : result; } #endif /* _DOUBLE_IS_32BITS */