123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- #include <limits.h>
- #include <math.h>
- #define SET_INVALID 0x01000000UL
- typedef union
- {
- struct {
- #if defined(__BIG_ENDIAN__)
- unsigned long int hi;
- unsigned long int lo;
- #else
- unsigned long int lo;
- unsigned long int hi;
- #endif
- } words;
- double dbl;
- } DblInHex;
- static const unsigned long int signMask = 0x80000000ul;
- static const double twoTo52 = 4503599627370496.0;
- static const double doubleToLong = 4503603922337792.0;
- static const DblInHex Huge = {{ 0x7FF00000, 0x00000000 }};
- static const DblInHex TOWARDZERO = {{ 0x00000000, 0x00000001 }};
- double rint ( double x )
- {
- DblInHex argument;
- register double y;
- unsigned long int xHead;
- register long int target;
-
- argument.dbl = x;
- xHead = argument.words.hi & 0x7fffffffUL;
- target = ( argument.words.hi < signMask );
-
- if ( xHead < 0x43300000ul )
- {
- if ( xHead < 0x3ff00000ul )
- {
- if ( target )
- y = ( x + twoTo52 ) - twoTo52;
- else
- y = ( x - twoTo52 ) + twoTo52;
- if ( y == 0.0 )
- {
- if ( target )
- return ( 0.0 );
- else
- return ( -0.0 );
- }
- return y;
- }
-
- if ( target )
- return ( ( x + twoTo52 ) - twoTo52 );
- else
- return ( ( x - twoTo52 ) + twoTo52 );
- }
-
- return ( x );
- }
|