why a == b
Because your compiler (gcc) calculated the values to initialize a
and b
with, and found (proved ?) both were matching or exceeding the maximum possible value for a long long
, so it initialized both with that maximum value LLONG_MAX
(or 0x7FFFFFFFFFFFFFFF
, or 9223372036854775807
on your platform).
Note that (as pointed out by Pascal Cuoq) this is undefined behaviour, caused by an overflow while converting a double
to a long long
when initializing a
and b
. While gcc deals with this as described above, other compilers can deal with this differently
I know that c ==d because of the precision of double
The reason c
and d
hold the same value is indeed because of the precision of a double
:
pow(2, 63)
can be accurately represented with fraction 1
and exponent 63
pow(2, 63) - 1
cannot be accurately represented
The reason it's not showing 9223372036854775808
(the precise value stored in c
and d
), is because of the printf
precision, which on your platform apparently only shows 17 digits. You might be able to force it to show more using eg. %20.0f
, but on Windows that will likely not make a difference due to this bug.
why (long long)c and (long long)d is not 9223372036854775800 ?
Because c
and d
hold the value 9223372036854775808
, or 0x8000000000000000
, which when printed as a signed value becomes -9223372036854775808
.
Note that this is again undefined behaviour (due to signed overflow).
why (long long)c != a and (long long)d != b?
Because they were calculated in different ways. a
and b
were calculated by the compiler, while (long long) c
and (long long) d
were calculated at runtime.
While normally, these different ways of calculating should yield the same results, we're dealing with undefined behaviour here (as explained earlier), so anything goes. And in your case, the compiler's results are different from the runtime results.