为什么此Java代码

long a4 = 1L;
long a3 = 1;
long a2 = 100L * 1024 * 1024 * 1024;
long a1 = 100 * 1024 * 1024 * 1024;
System.out.println(a4);
System.out.println(a3);
System.out.println(a2);
System.out.println(a1);

运行时,输出

1
1
107374182400
0

而不是预期的

1
1
107374182400
107374182400

输出?

有帮助吗?

解决方案 2

107374182400正好是整数的25倍(2^32), ,这意味着,如果您试图将其安装到整数中,它将 溢出. 。而且,由于它将完全适合25倍,因此准确地结合了0(这是一个巧合,其他巨大的乘法可能最终是正面或负面的)。而且,您正在使用一个整数,直到您铸造为长时间

long a1 = 100 * 1024 * 1024 * 1024;

等同于

int temp = 100 * 1024 * 1024 * 1024;
long a1 = (long)temp;

如果您在表达式中放了一个长时间,则被迫使用长数学而不是整数数学来消除问题

其他提示

 long a2 = 100L * 1024 * 1024 * 1024;

在此操作中,至少有一个操作数是 long. 。因此,使用64位精度进行操作,数值操作员的结果是类型 long. 。另一个非长操作数被扩大到类型 long 经过 数字促进 并将结果存储到变量 a2.

 long a1 = 100 * 1024 * 1024 * 1024;

普通整数的恒定表达式,将表达式的结果计算为一种类型 int. 。计算值但是太大而无法适合整数并因此溢出,从而导致 0 并存储到 a1 多变的。

编辑:如以下评论所要求的:

为什么不负面?

因为在 整数计算 第二个计算等同于 25 * 2^32 在哪里 ^ 具有力量含义和 2^32 整数值是 0. 。但是,解释为什么它的价值是 0: :in Binary:

 100 * 1024 * 1024 * 1024 == 25 * 2^32;

 Integer.MAX_VALUE =  2 ^ 31 -1 = 0 11111111 11111111 11111111 1111111
 Integer.MAX_VALUE + 1 = 2 ^ 31 = 1 00000000 00000000 00000000 0000000 

2 ^ 31 是一个负整数(-2147483648),因为符号是 1 因此 2 ^ 32 只是 22 ^ 31: :左移,标志钻头会变成 0 因此结果是 0.

查看 java language specification: 4.2.2: Integer operation 有关详细信息。

可能是在右边的表达 a1 首先计算为 int 后来转换为 long. 。如果它等于 0 作为一个 int 它会留下来 0 作为一个 long

按照 词汇文字的文档 提到,

字面的类型确定如下:
- 以l或l结尾的整数文字(第3.10.1节)的类型是长的(第4.2.1节)。
- 任何其他整数文字的类型是INT(§4.2.1)。

因此,您的表情, 100 * 1024 * 1024 * 1024 被评估为 int 原始数据类型是因为 l 或者 L 没有在任何数字值中提及。结果是 107374182400 即二进制是 1 1001 0000 0000 0000 0000 0000 0000 0000 0000int 是32位如此低的32位,如前所述 示例4.2.2-1。整数操作 结果 0

在同一文档中也提到了,

如果除移动运算符以外的整数操作员至少具有一个类型长的操作数,则使用64位精度进行操作,并且数值操作员的结果是类型长。如果另一个操作数不长,则首先将其扩大(第5.1.5节),以数字促销键

这意味着表达式中的任何值都包含 l 或者 L 然后所有 int 值将扩展到64位。

编辑评论 也被问到

为什么不负面?

我认为这也是 回答上述问题

long a4 = 1L; //这没问题

long a3 = 1; //这里的左侧原始词被认为是整数,在作业时,它将被施加到很长时间,因此结果再次如预期

long a2 = 100L * 1024 * 1024 * 1024; (在这里您使用了100升,因此其他类型会被铸造为长期如此期待的输出)

long a1 = 100 * 1024 * 1024 * 1024; (默认情况下,任何原始数字在Java中都被认为是INT,它将将其视为整数乘法,因此它脱离范围并导致0)

这是您所做的:您分配了 100 * 1024 * 1024 * 1024长期数据类型,但您没有说 100 * 1024 * 1024 * 1024 是一个长的价值

默认情况下,Java编译器认为它是一个整数。由于整数无法保持那么多价值,因此会显示错误的结果。希望能帮助到你 !

原因是 整数溢出
作为输出 100 * 1024 * 1024 * 1024; 是一个整数(int) 不是 long

并在 long a2 = 100L * 1024 * 1024 * 1024; 您正在指定该值之一是 long (这里 100L)和与该值的乘法导致 long 值正确存储在 a2

在Java中,如果您具有INT * INT,则将其计算为INT。如果您做长时间,它只会给出结果。在您的情况下,100 * 1024 * 1024 * 1024的结果会溢出int。

因此,添加“ L”使操作数变长,并且计算将值存储在长时间中。当然,不会发生溢出,并且可以输出正确的结果(即A2)。

第3号工作是因为您指定了100L的长类型。这就是为什么它是一个长乘法并可以存储的原因。另一方面,数字4是一个具有最大值2^32-1的整数乘法,这就是为什么您会出现溢出并且出现零默认值的原因。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top