为什么以下语句在 Java 中给出不同的输出?
Why do the following statements give different outputs in Java?
对于 x 的某些值(x 是 long 类型),
x %= (1e9+7);
和
x %= 1_000_000_007;
给出不同的答案。知道为什么会这样吗?
此外,这种下划线格式 (1_000_000_007) 是否跨语言通用?除了增强可读性之外,它还有其他优势吗?
这是因为1e9
是一个double
字面量,并不是每个long
值都可以精确表示为double
,所以会损失精度由于从 long
到 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 在操作数上,将 x
转换为类型 double
.
由于double
是双精度IEEE 754 floating-point number,它的尾数有53位精度,不足以表示所有64位精度long
值可能要求。换句话说,double
和long
都使用64位,但是有很多double
值不是long
值,因此也一定有很多long
值不是 double
值。因此,对于大于 253 或小于 -253 的值,从 long
到 double
的隐式转换会导致精度损失.
顺便说一下,由于取余运算,由于精度损失导致的误差可能高达 109 + 7 本身。例如,对于输入值 9_223_372_036_563_603_804L
,错误是 999_999_659
。
对于 x 的某些值(x 是 long 类型),
x %= (1e9+7);
和
x %= 1_000_000_007;
给出不同的答案。知道为什么会这样吗?
此外,这种下划线格式 (1_000_000_007) 是否跨语言通用?除了增强可读性之外,它还有其他优势吗?
这是因为1e9
是一个double
字面量,并不是每个long
值都可以精确表示为double
,所以会损失精度由于从 long
到 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 在操作数上,将 x
转换为类型 double
.
由于double
是双精度IEEE 754 floating-point number,它的尾数有53位精度,不足以表示所有64位精度long
值可能要求。换句话说,double
和long
都使用64位,但是有很多double
值不是long
值,因此也一定有很多long
值不是 double
值。因此,对于大于 253 或小于 -253 的值,从 long
到 double
的隐式转换会导致精度损失.
顺便说一下,由于取余运算,由于精度损失导致的误差可能高达 109 + 7 本身。例如,对于输入值 9_223_372_036_563_603_804L
,错误是 999_999_659
。