代码之家  ›  专栏  ›  技术社区  ›  chedine

关于Java的int的基本问题

  •  8
  • chedine  · 技术社区  · 16 年前

        i = (int)Math.pow(2,31) ;
        System.out.println(i);
    

    i = (int)Math.pow(2,31) +1 ;
    System.out.println(i);
    

    我是整数类型。如果第二个代码样本(两个整数的加法)可以在结果超出正范围时换行到负的一侧,那么为什么第一个样本不能换行呢? 也,

    i = 2147483648 +1 ;
    System.out.println(i);
    

    这与第二个代码示例抛出的编译错误非常相似,即第一个文本超出整数范围?

    2 回复  |  直到 16 年前
        1
  •  12
  •   mdma    16 年前

    对于第一个代码示例,结果从 double 到一个 int JLS 5.1.3 描述如何将double转换为int。

    相关部分是:

    大幅度的正值或 正无穷大),以及 int或 很长。

    这就是为什么2^31(2147483648)减少为Integer.MAX_VALUE (2147483647). 同样的情况也适用于

    i = (int)(Math.pow(2,31)+100.0) ;  // addition note the parentheses
    

    i = (int)10000000000.0d;   // == 2147483647
    

    在第二个例子中,当加法没有括号时,我们将处理整数加法。积分类型使用 2's complement

     0x7FFFFFFF   (2147483647)
    

    给予

     0x80000000
    

    overflow flag 当算术运算溢出或下溢时。语言运行时可以检查这个标志,尽管这会带来额外的开销,有些人认为这是不必要的。

    JLS 3.10.1 - Integer Literals .

        2
  •  4
  •   Mark Byers    16 年前

    那么为什么像这样的代码会自动换行到负片并打印-2147483648呢?

    这称为溢出。Java这样做是因为C这样做。C之所以这样做是因为大多数处理器都这样做。在某些语言中,这种情况不会发生。例如,某些语言会抛出异常,而另一些语言则会将类型更改为可以保存结果的类型。

    我的问题是,对于第二个代码示例,为什么第一个和第三个示例不能自动包装到另一边?

    关于第一个项目: Math.pow

    关于您的第三个程序:溢出很少是一个理想的属性,并且常常是您的程序不再工作的标志。如果编译器可以看到它仅仅通过计算一个 几乎可以肯定 代码中的错误。如果你 一个大的负数,为什么要写一个大的正数?