Use frexp() to get you mostly. It splits the number into exponential and value (fraction).
Suppose long is at least the same size as double , otherwise it is pointless. Pigeonhole principle .
#include <math.h> long f(double x) { assert(sizeof(long) >= sizeof(double)); #define EXPOWIDTH 11 #define FRACWIDTH 52 int ipart; double fraction = frexp(fabs(x), &ipart); long lg = ipart; lg += (1L << EXPOWIDTH)/2; if (lg < 0) ipart = 0; if (lg >= (1L << EXPOWIDTH)) lg = (1L << EXPOWIDTH) - 1; lg <<= FRACWIDTH; lg += (long) (fraction * (1L << FRACWIDTH)); if (x < 0) { lg = -lg; } return lg; }
-
Notes:
The eigenvalue for EXPO depends on DBL_MAX_EXP and DBL_MIN_EXP and information about the double type.
This solution displays the same double values ββnear the extrema of the double . I will look and test later.
Otherwise, as stated above: superimpose two types.
Since long often 2 additions, and double is laid out using the sign method, additional work is required when double negative. Also watch out for -0.0.
long f(double x) { assert(sizeof x == sizeof (long)); union { double d; long lg; } u = { x*1.0 };
chux
source share