1

I apologize if this has been asked before, but I read through many DBL_MAX threads and didn't see this exact issue.

In my float.h header the variable is defined as

#define DBL_MAX         1.7976931348623158e+308 /* max value */

However, whenever I try to print it in the console, I end up with 1.7976931348623157e+308 instead.

If this is supposed to be the maximum representable value, shouldn't it print correctly, without being rounded down? I have also set out.precision to the maximum value for doubles.

Can anyone explain why this is happening and advise whether or not there is a way to print out DBL_MAX unchanged?

gsamaras
  • 71,951
  • 46
  • 188
  • 305

1 Answers1

2

You're getting the correct behaviour at both ends.

The maximum value representable in the so-called binary64 double representation your system seems to be using has an exponent of 1023, and a fraction of 1 - 2-52, to give (1 + 1-2-52)*21023 = (21+52-2-52+52)*21023-52 = (253-1)*2971, which according to bc evaluates to exactly

$ bc <<< '(2 ^ 53 - 1) * (2 ^ 971)'
17976931348623157081452742373170435679807056752584499659891747680315\
72607800285387605895586327668781715404589535143824642343213268894641\
82768467546703537516986049910576551282076245490090389328944075868508\
45513394230458323690322294816580855933212334827479782620414472316873\
8177180919299881250404026184124858368

As you can see, this is 1.797693134862315708...e+308, which is nearer to 1.7976931348623157e+308 than it is to 1.7976931348623158e+308, which explains why you see 7 just before the e when printing this number.

However, the constant in the header has a slightly different purpose: its purpose is to always, no matter how the compiler is configured, give that exact floating-point number. Defining the constant as 1.7976931348623157e+308 would be incorrect, since that number is not exactly representable, the compiler is forced to round to either the previous or the next representable floating-point value, and it's possible that the compiler is configured to round down. Defining the constant as 1.7976931348623158e+308 does not have that problem, because it does not allow the compiler to round up, because there is no next (finite) value.