【问题标题】:Java - TypeCasting QuestionJava - 类型转换问题
【发布时间】:2010-12-16 02:15:35
【问题描述】:
long a = (long)Math.pow(2, 32);
// a = 4294967296 :)

long a = (int)(long)Math.pow(2, 32);
//a = 0 ?!

long a = (int)Math.pow(2, 32);
//a = 2147483647 WTF??!!!

第一个表达式很明显。 a 按原样打印。

第二个表达式有点混乱。大值是

100000000000000000000000000000000 // 1 后跟 32 个零,总共 33 位

当它被强制为int时,它是如何被为零的?它不应该将最重要的 1 作为符号位并认为该数字是 -2147483648 吗? [疑点清除]

另外,当从 Math.pow (4.294967296E9) 返回的 double 直接转换为 int 时,为什么是 2147483647?

我正在阅读一本书的类型转换和数据类型,但文本并没有解释太多。我很困惑。请解释为什么第二个和第三个表达式会产生这些结果。

【问题讨论】:

    标签: java casting


    【解决方案1】:

    不,因为据我所知,它会截断前 32 位之后的所有内容 - 所以它不知道开头的 1(或者更确切地说,是结尾)。

    4294967296 = 0x100000000(十六进制),只取前 32 位给你零。

    编辑:我实际上认为另一个与从浮点到 int 的特殊转换有关,这与通过 long 然后再进行 int 不同,因为它是对处理器的完全不同类型的转换.

    【讨论】:

    • 您是说它会截断前 32 位之后的所有内容。但是当写成二进制数时,1 在“前 32 位”内。如果有 32 个零然后有一个 1,那么您所说的将是正确的。但是有 31 个零,然后是一个 1。如果它截断超过 32 位,则不应截断 1!
    • 2^32 是一个 1 后跟 32 个二进制零。同样,10^10 是一个 1,后跟 10 个十进制零。 coppervinesoftware.com/2to32.png
    • 糟糕!我的错。抱歉 :) 现在我明白了.. :D +1
    • 0x100000000 有 8 个零,所以这是 8*4=32 零位。 1 是第 33 位,被丢弃。
    【解决方案2】:

    Java 规范的第 5.1.3 节涵盖了这一点。

    http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363

    整数缩小只取最低的 n 位,这意味着不考虑符号。而且,事实上,负数可能会变成正数。 Widening 没有这个属性,并且会将数字符号扩展为更宽的类型。

    int value = (int)(long)(Math.pow(2, 31)); // double to long to int
    System.out.println(value); // Prints -2147483648
    
    long lvalue = value; // int back to long
    System.out.println(value); // Prints -2147483648 again
    

    浮点缩小是一个复杂得多的过程,它基本上将数字截断为目标类型中可能最接近的表示形式,向零舍入。在这种情况下,会触发上溢/下溢规则,将浮点数分别转换为该类型可表示的最大值/最小值。

    【讨论】:

    【解决方案3】:

    来自spec,部分5.1.3。 T 是 byte、short、char 或 int 之一。

    有符号整数到整数类型 T 的窄化转换只会丢弃除 n 个最低位之外的所有位,其中 n 是用于表示类型 T 的位数。除了可能丢失有关数值,这可能会导致结果值的符号与输入值的符号不同。

    你最终得到的是低位,这使得这种情况变为 0。

    【讨论】:

    • 如果这本该死的书有这 4 行就好了。一整页的文字描述了其他所有内容,但您从规范中引用的内容。感谢您清除它:) +1.. 我怀疑符号位会被忽略但无法确认。
    • 你为java提供的“spec”链接是最新的吗?
    • 第一个链接指向最新版本,第二个链接指向上一版本。但是类型转换没有改变,新的 Java 版本完全兼容,只是添加了一些新的东西,比如泛型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    相关资源
    最近更新 更多