This is because 1e9
is a double
literal, and not every long
value can be exactly represented as a double
, so there is a loss of precision due to an implicit conversion from long
to double
.
According to the language specification, x %= d
is equivalent to x = (long) (x % d)
when x
is a variable of type long
and d
is of type double
. The remainder operation also performs binary numeric prommotion on the operands, which converts x
to type double
.
Since double
is a double-precision IEEE 754 floating-point number, it has 53 bits of precision for the mantissa, which is insufficient to represent all 64 bits of precision a long
value may require. Put another way, both double
and long
use 64 bits, but there are many double
values which are not long
values, therefore there must also be many long
values which are not double
values. So the implicit conversion from long
to double
can result in a loss of precision for values greater than 253 or less than -253.
By the way, because of the remainder operation, the error due to loss of precision could be up to 109 + 7 itself. For the input value 9_223_372_036_563_603_804L
the error is 999_999_659
, for example.