首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在案例2: on Java 7中有两个不同的答案是相同的?

为什么在案例2: on Java 7中有两个不同的答案是相同的?
EN

Stack Overflow用户
提问于 2017-01-18 12:57:08
回答 2查看 220关注 0票数 3

为什么在案例2: on Java 7中有两个不同的答案是相同的?

代码语言:javascript
复制
class Ideone
{
  public static void main (String[] args) throws java.lang.Exception
  {
    System.out.println("Case 1:"); 
    long size=(long)1<<39;
    System.out.println("size :"+size); 
    size=1024*1024*1024*512l;
    System.out.println("size :"+size);  
    System.out.println("Case 2:"); 
    size=(long)1<<41;
    System.out.println("size :"+size); 
    size=1024*1024*1024*1024*2l;
    System.out.println("size :"+size);
  }
}

下面是Ideone给出的答案。

代码语言:javascript
复制
Case 1:
size :549755813888
size :549755813888 
Case 2:
size :2199023255552
size :0
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-18 13:21:44

你看到零的原因是因为它是整数溢出。在这个确切的场景中,您将触发JLS乘法算子,它声明低端位将是溢出的结果。

例如

代码语言:javascript
复制
System.out.println((1025*1024*1024*1024*2));
System.out.println(Integer.toBinaryString(1025*1024*1024*1024*2));

会打印出来

代码语言:javascript
复制
-2147483648 // Integer overflow
10000000000000000000000000000000 // Integer overflow

在你的情况下

代码语言:javascript
复制
System.out.println((1024*1024*1024*1024*2)); 
System.out.println(Integer.toBinaryString(1024*1024*1024*1024*2));

它会打印出来

代码语言:javascript
复制
0 // still a overflow, but the lower ordered bits are 0, since we dont see trailing zero bits
0

所以确切地说,计算是从整数开始的。

代码语言:javascript
复制
size=1024*1024*1024*1024*2l;

如果你不声明它是长的,它就不会这样处理它。要修复它,您必须在第一个操作数中使用大写L或小写l

代码语言:javascript
复制
 size=1024L*1024*1024*1024*2l;

    System.out.println((1024L*1024*1024*1024*2l));
    System.out.println(Integer.toBinaryString(1024L*1024*1024*1024*2l)); // will not work, because the compiler knows it's a long
    System.out.println(Long.toBinaryString(1024L*1024*1024*1024*2l));

结果是

代码语言:javascript
复制
2199023255552 // long value
100000000000000000000000000000000000000000
票数 5
EN

Stack Overflow用户

发布于 2017-01-18 13:33:47

案例1

1024是int。因此,1024 * 1024 * 1024在int算法中执行,也就是说,以32位执行。因为1024是2^10,1024 * 1024 * 1024是2^30,所以它适合32位int。接下来,乘以512 L,即long (请使用大写L,很容易将一个小l误读为数字1)。因此,将2^30转换为long,并将两个long值相乘。结果是2^39,它适合于long (不适合于int)。一切都很好。

案例2

1024 * 1024 * 1024和以前一样是2^30,和以前一样是int。下一个1024也是在int中,所以下一个乘法是用32位算术和溢出完成的,因为结果是2^40,这是不适合的。因为这个数字以32个零结尾,结果是0。这现在被转换为long (0L),因此它可以乘以2L。0*2是0(不管是32位还是64位)。

Fix

如前所述,技术上只要在溢出发生之前将其中一个常量标记为long (使用L)就足够了。1024 * 1024 * 1024 * 1024L * 21024L * 1024 * 1024 * 1024 * 2应该能工作。不过,我更喜欢1024L * 1024L * 1024L * 1024L * 2L。我发现它更容易阅读和理解。其他我觉得不错的选项包括1L << 410x200_0000_0000

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41720044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档