当前位置: 首页 > 知识库问答 >
问题:

为什么int i=1024 * 1024 * 1024 * 1024编译没有错误?

孟凯泽
2023-03-14

int的限制是从-2147483648到2147483647。

如果我输入

int i = 2147483648;

然后Eclipse会在“2147483648”下提示红色下划线。

但是如果我这样做:

int i = 1024 * 1024 * 1024 * 1024;

很好。

public class Test {
    public static void main(String[] args) {        

        int i = 2147483648;                   // error
        int j = 1024 * 1024 * 1024 * 1024;    // no error

    }
}

也许这是Java中的一个基本问题,但我不知道为什么第二个变体不会产生错误。

共有3个答案

章涵蓄
2023-03-14

我不知道为什么第二个变体不会产生错误。

您建议的行为——即,当计算产生的值大于可存储在整数中的最大值时,产生诊断消息——是一个特性。要使用任何功能,必须考虑该功能,将其视为一个好主意,设计、指定、实施、测试、记录并发送给用户。

对于Java,该列表中的一个或多个事件没有发生,因此您没有该功能。我不知道是哪一个;你得问问Java设计师。

对于C#,所有这些事情都发生了——大约14年前的现在——因此C#中相应的程序自C#1.0以来产生了一个错误。

奚昌胤
2023-03-14

1024*1024*1024*10242147483648在Java中没有相同的值。

实际上,2147483648在Java中甚至不是一个值(尽管2147483648L是)。编译器实际上不知道它是什么,也不知道如何使用它。所以它哀鸣着。

1024在Java中是一个有效的int,一个有效的int乘以另一个有效的int,总是一个有效的int。即使它不是你直觉上期望的值,因为计算会溢出。

考虑以下代码示例:

public static void main(String[] args) {
    int a = 1024;
    int b = a * a * a * a;
}

你认为这会产生编译错误吗?现在有点滑了
如果我们把一个循环放在3次迭代中,然后在循环中相乘,会怎么样?

编译器可以进行优化,但在进行优化时不能改变程序的行为。

关于本案实际处理方式的一些信息:

在Java和许多其他语言中,整数将由固定数量的位组成。不符合给定位数的计算将溢出;在Java中,计算基本上是以模2^32执行的,然后将值转换回有符号整数。

其他语言或应用编程接口使用动态位数(Java中的Bigintger),引发异常或将值设置为一个神奇的值,如非数字。

东郭宏朗
2023-03-14

这句话没有错;你只是将4个数字相乘,并将其分配给一个整数,正好有一个溢出。这与分配单个文本不同,后者将在编译时进行边界检查。

导致错误的是出界字面值,而不是赋值:

System.out.println(2147483648);        // error
System.out.println(2147483647 + 1);    // no error

相比之下,longliteral可以很好地编译:

System.out.println(2147483648L);       // no error

请注意,实际上,结果仍然是在编译时计算的,因为1024*1024*1024*1024是一个常量表达式:

int i = 1024 * 1024 * 1024 * 1024;

变成:

   0: iconst_0      
   1: istore_1      

请注意,结果(0)只是简单地加载和存储,没有发生乘法。

来自JLS§3.10.1(感谢@ChrisK在评论中提出):

如果int类型的十进制文字大于2147483648(231),或者十进制文字2147483648出现在一元减号运算符(§15.15.4)操作数以外的任何地方,则为编译时错误。

 类似资料:
  • 问题内容: 上限为-2147483648至2147483647。 如果我输入 然后Eclipse将在“ 2147483648”下提示红色下划线。 但是,如果我这样做: 它将编译良好。 也许这是Java中的一个基本问题,但是我不知道为什么第二个变体不会产生任何错误。 问题答案: 那句话没有错。您只是将4个数字相乘并将其分配给一个int,恰好发生溢出。这与分配单个 文字 不同,后者在编译时会进行边界检

  • 1024 1024是一个基于Java 的小游戏。 游戏规则 可将活动方块向上,下,左,右4个方向移动 相同数字的方块碰撞到一起可合并为一个方块,合并的方块数字为2者之和 操作 选中:单击目标方块 移动:上(W),下(S),左(A),右(D)  重新开始:空格(Space) 演示 数字与颜色对照表 对应的数字依次为2的N次方 版权 本软件遵循GPL(GNU GENERAL PUBLIC LICENS

  • 问题内容: 如何转换此C(数组)类型: 转到此Go(数组)类型: ?尝试进行接口转换会给我这个错误: 问题答案: 最简单,最安全的方法是将其复制到切片中,而不是专门复制到 要直接使用内存而不进行复制,可以通过来“广播” 。

  • 问题内容: 在Java中将字符串拆分为1024个字节的块的有效方法是什么?如果有多个块,则需要在所有后续块中重复标头(固定大小的字符串)。 问题答案: 字符串和字节是完全不同的两件事,因此要将字符串拆分为字节与将绘画拆分为经文一样没有意义。 您实际上想做什么? 要在字符串和字节之间进行转换,您需要指定一种编码,该编码可以对String中的所有字符进行编码。根据编码和字符,其中一些可能跨越一个以上的

  • 在iOS10中,NSlog限制为1024个字符,任何人都知道打印完整字符串的解决方法。

  • 我正在使用最新版本的骆驼和Netty与Spring,并且具有以下定义: 我定义了一个类来处理传入的tcp请求: 我的问题是,不管传入消息的大小,buf变量永远不会超过1024字节,因此我的请求被截断。 根据组件定义,receiveBufferSize应该是65536字节。我如何处理大的请求?