Pregunta

What should the output of the following program be?

#include <stdio.h>
#include <math.h>
#include <float.h>

int main() {
    int exp;
    float mant = frexp(FLT_MAX, &exp);
    printf("frexp(%a) = {%f, %d}\n", FLT_MAX, mant, exp);
    return 0;
}

On my amd64 Linux system with glibc it prints:

frexp(0x1.fffffep+127) = {1.000000, 128}

From the IEEE 754 Wikipedia article I see that the "Largest normalized number" has an exponent of 127. I also see that the only values with an exponent of 128 are ±Infinity and NaN.

From the frexp man page I understand that frexp() should return a value in the range [0.5, 1.0) (that is, excluding 1.0).

Both the mantissa and exponent returned seem to be incorrect based on those pieces of information.

Knowing what frexp() does and the value of FLT_MAX (= (2 - 2^-23) * 2^127) tells me that {1.0, 128} is indeed very close to the correct answer, since (2 - 2^-23) is very close to 2.

So what should frexp(FLT_MAX, ...) return?

¿Fue útil?

Solución

I give you credit for printing FLT_MAX out in %a format, so you can see what the value actually is, as opposed to what %f prints it as. So why not do that for the value of mant, too?

frexp(0x1.fffffep+127) = {0x1.fffffep-1, 128}

That result seems unsurprising to me. (Note that the exponent in the IEEE-754 representation is based on a mantissa in the range [1.0, 2.0), whereas frexp generates a mantissa in the range [0.5, 1.0). So the frexp maximum exponent is one higher.)

Moral: Never confuse what a floating point value is with how it looks.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top