#include #include union stg_ieee754_dbl { double d; struct { #if WORDS_BIGENDIAN unsigned int negative:1; unsigned int exponent:11; unsigned int mantissa0:20; unsigned int mantissa1:32; #else #if FLOAT_WORDS_BIGENDIAN unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; unsigned int mantissa1:32; #else unsigned int mantissa1:32; unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; #endif #endif } ieee; /* This format makes it easier to see if a NaN is a signalling NaN. */ struct { #if WORDS_BIGENDIAN unsigned int negative:1; unsigned int exponent:11; unsigned int quiet_nan:1; unsigned int mantissa0:19; unsigned int mantissa1:32; #else #if FLOAT_WORDS_BIGENDIAN unsigned int mantissa0:19; unsigned int quiet_nan:1; unsigned int exponent:11; unsigned int negative:1; unsigned int mantissa1:32; #else unsigned int mantissa1:32; unsigned int mantissa0:19; unsigned int quiet_nan:1; unsigned int exponent:11; unsigned int negative:1; #endif #endif } ieee_nan; }; double c_succ(double y) { union stg_ieee754_dbl su; su.d=y; if (su.ieee.negative==0) { /* y >= 0 */ if (su.ieee.exponent!=2047 || su.ieee.mantissa0!=0 || su.ieee.mantissa1!=0) if (su.ieee.mantissa1==0xffffffff) { su.ieee.mantissa1=0; if (su.ieee.mantissa0==1048575) { su.ieee.mantissa0=0; su.ieee.exponent++; } else { su.ieee.mantissa0++; } } else { su.ieee.mantissa1++; } } else { /* y < 0 */ if (su.ieee.exponent!=2047 || su.ieee.mantissa0!=0 || su.ieee.mantissa1==0){ if (su.ieee.negative==1 && su.ieee.exponent==0 && su.ieee.mantissa0==0 && su.ieee.mantissa1==0) { su.ieee.negative=0; su.ieee.mantissa1=1; } else { if (su.ieee.mantissa1==0) { su.ieee.mantissa1=0xffffffff; if (su.ieee.mantissa0==0) { su.ieee.mantissa0=1048575; su.ieee.exponent--; } else { su.ieee.mantissa0--; } } else { su.ieee.mantissa1--; } } } } return su.d; } /* end function q_succ */ double c_pred(double y) { union stg_ieee754_dbl su; su.d=y; if (su.ieee.negative==1) { /* y < 0 */ if (su.ieee.exponent!=2047 || su.ieee.mantissa0!=0 || su.ieee.mantissa1!=0 ) if (su.ieee.mantissa1==0xffffffff) { su.ieee.mantissa1=0; if (su.ieee.mantissa0==1048575) { su.ieee.mantissa0=0; su.ieee.exponent++; } else { su.ieee.mantissa0++; } } else su.ieee.mantissa1++; } else { /* y >= 0 */ if (su.ieee.exponent!=2047 || su.ieee.mantissa0!=0 || su.ieee.mantissa1!=0) if (su.ieee.exponent==0 && su.ieee.mantissa0==0 && su.ieee.mantissa1==0) { su.ieee.negative=1; su.ieee.mantissa1=1; } else { if (su.ieee.mantissa1==0) { su.ieee.mantissa1=0xffffffff; if (su.ieee.mantissa0==0) { su.ieee.mantissa0=1048575; su.ieee.exponent--; } else { su.ieee.mantissa0--; } } else { su.ieee.mantissa1--; } } } return su.d; } /* end function q_pred */