00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <errno.h>
00038
00039 extern int errno;
00040
00041 typedef union
00042 {
00043 long long lword;
00044 double d;
00045 } du;
00046
00047 static const du Quiet_nan =
00048 {
00049 0x7ff8000000000000ll,
00050 };
00051
00052 extern double fabs(double);
00053
00054 #ifdef mips
00055 extern double trunc(double);
00056
00057 #pragma weak trunc = __trunc
00058 #endif
00059
00060 #if defined(BUILD_OS_DARWIN)
00061 extern double __trunc(double);
00062 #pragma weak trunc
00063 double trunc( double arg ) {
00064 return __trunc( arg );
00065 }
00066 #elif defined(__GNUC__)
00067 extern double __trunc(double);
00068 double trunc() __attribute__ ((weak, alias ("__trunc")));
00069 #endif
00070
00071 #define DMANTWIDTH 52
00072 #define DEXPWIDTH 11
00073 #define DSIGNMASK 0x7fffffffffffffffll
00074 #define DEXPMASK 0x800fffffffffffffll
00075 #define DQNANBITMASK 0xfff7ffffffffffffll
00076
00077 #define MANTWIDTH 23
00078 #define EXPWIDTH 8
00079 #define SIGNMASK 0x7fffffff
00080 #define EXPMASK 0x807fffff
00081 #define QNANBITMASK 0xffbfffff
00082
00083 double
00084 __trunc( double arg )
00085 {
00086 unsigned long long ll, exp, mantissa;
00087 int sign;
00088 int shift_count;
00089 double result;
00090
00091
00092 ll = *(unsigned long long *)&arg;
00093
00094 exp = (ll >> DMANTWIDTH);
00095 sign = (exp >> DEXPWIDTH);
00096 exp &= 0x7ff;
00097 mantissa = (ll & (DSIGNMASK & DEXPMASK));
00098
00099 if ( exp == 0x7ff )
00100 {
00101
00102
00103 if ( mantissa == 0 )
00104 return ( arg );
00105 else
00106 {
00107 errno = EDOM;
00108 return ( Quiet_nan.d );
00109 }
00110 }
00111
00112 if ( exp >= 0x433 )
00113 return ( arg );
00114
00115 if ( fabs(arg) < 1.0 )
00116 return ( (sign == 0) ? 0.0 : -0.0 );
00117
00118 shift_count = 0x433 - exp;
00119
00120 ll >>= shift_count;
00121 ll <<= shift_count;
00122
00123 *(long long *)&result = ll;
00124
00125 return ( result );
00126 }
00127