cfloating-pointbinary-datamath.h

In C, extract mantissa of a double as a long long in portable way


Function frexp(3) returns the normalized mantissa xm of a double x, with a value in [0.5,1.0), unless x=0. So I can convert it to a long long as follows:

    int ie; // will be set in next line
    const double xm = frexp(x, &ie); // from math.h; sets xm and ie
    const long long ix = ldexp(xm, 53); // xm*2**53, rounded to long integer

However, this feels less than optimum because of the intermediary double value returned by function ldexp(3). Is there a more direct, and no less portable, way of extracting ix from x?


Solution

  • Is there a more direct, and no less portable, way of extracting ix from x?

    No.

    That's basically the way to do it. It "feels less than optimum", but frexp() really is the portable way of busting up a double. It used to bug me that frexp() gave me the significand as another double, but I've gotten used to it, and there are decent reasons for that choice.
    @Steve Summit

    #include <float.h>
    #include <math.h>
    
    if (isfinite(x)) {
      int ie;
      double xm = frexp(x, &ie);
      long long ix = scalbn(xm, DBL_MANT_DIG);
    }
    

    Portability: Note that the number of bits in the double significand may exceed the widest integer type.