2011-02-28 37 views
4

范围我有int值怀疑具有int变量

int x=2147483647;  /*NO Error--this number is the maximum range 
         of int value no error*/ 
int y=2147483648;  /*Error--one more than the 
         maximum range of int*/ 
int z=2147483647+1; /*No Error even though it is one more 
         than the maximum range value*/ 

为什么范围内的疑问?

回答

8

下面是关于Java语言规范的解释。

上整数常量(JLS 3.10.1)的部分这样说:

最大十进制字面int类型是2147483648(2 )。从02147483647的所有十进制文字可以出现在可能出现整型文字的任何位置,但文字2147483648可能仅出现在一元否定运算符-的操作数中。

所以......

  • 第一条语句是一个合法的整数文字值的分配。没有编译错误。

  • 第二个声明是编译错误,因为2147483648不在一元否定运算符之前。

  • 第三条语句不包含超出范围的整数字面值,因此从该角度看它不是编译错误。

而是,第三种说法是如JLS 15.18.2中所述的二进制加法表达式。这说明了整数大小写如下:

如果整数加法溢出,那么结果就是以一些足够大的二进制补码格式表示的数学和的低位。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

因此,2147483647 + 1溢出并包装到-2147483648


@Peter Lawrey的建议(轻率?)第三语句可“由编译器重写”为+2147483648,导致编译错误。

这是不正确的。

JLS中没有任何内容表明常量表达式可以与非常量表达式具有不同的含义。相反,在例如1/0的情况下,JLS翻转事物并且说该表达式不是一个常量表达式,因为它异常终止。 (它在JLS 15.28

JLS极力避免某些Java构造意味着不同事情的情况,这取决于编译器。例如,“明确赋值”规则非常特别,以避免只有智能编译器可以推断出该变量在使用之前始终被初始化的情况。从代码可移植性的角度来看,这是一件好事。

编译器实现者为了执行特定于平台的事情而存在“摆动空间”的唯一重要领域是并发性和Java内存模型。有一个合理的实用原因 - 允许多线程Java应用程序在多核/多处理器硬件上快速运行。

1

因为第三个被称为整数溢出。你正在做计算,你溢出。其他的只是常数。

+0

对不起,我没有得到你 – satheesh 2011-02-28 09:36:07

1

由于

int z=2147483647+1; 

会溢出,这是不等于2147483648

+0

它是在运行时进行名义上的评估,但编译器可以在编译时简化这个表达式。 ;)'z ==(int)2147483648' – 2011-02-28 09:38:11

+1

但它是常量表达式rite.all常量表达式将在编译时自己评估知道 – satheesh 2011-02-28 09:38:26

+0

优化不应该改变某些东西的行为。仅仅因为编译器可以优化代码不应该导致它产生错误。例如'Integer i = 0/0;即使它在运行时产生aException,它仍然会编译。我的IDE显示此表达式的警告。 – 2011-02-28 09:41:10

0

第三个表达式是基于INT-此外,因此它将结果转换为INT的范围内的值。

0

int的范围是Integer.MIN_VALUEInteger.MAX_VALUE。 Java很容易溢出,因此编译器无法检测到计算结果。 (但可能被你的IDE来检测)

其中最令人吃惊的溢出业务是-Integer.MIN_VALUE

2

int范围从Integer.MIN_VALUE (-2147483648)Integer.MAX_VALUE (2147483647)

但是,只有int文字会根据范围进行检查。

Java不检查任何给定的常量值表达式是否在该范围内。

计算“允许”通过这些边界,但这会导致溢出(即只有结果值的低位将被存储)。因此,计算2147483647 + 1int计算中明确定义的,它是-2147483648。

+0

你给java没有检查任何给定的常量值表达式适合在该范围内。是否适用于每个地方 – satheesh 2011-02-28 09:48:09

+0

是的,正如运行时计算一样,常量值表达式只会溢出。只检查文字值(并且会导致编译器错误)。尝试打印'Double.MIN_VALUE/10'或'Double.MAX_VALUE + 10 - Double.MAX_VALUE'。 – 2011-02-28 09:50:37

+0

那么为什么我得到编译时错误字节r = 127 + 1 – satheesh 2011-02-28 09:58:42

1

前两种情况似乎很明显。第三种情况将无声无息地溢出。所以在这种情况下,您应该始终在您的调用代码中处理该问题。