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.