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个ZERO,全部为33位
当它被强制转换为int时,如何将其视为ZERO?不应该把最重要的1作为符号位并认为该数字是-2147483648? [DOUBT CLEARED]
另外,当从Math.pow(4.294967296E9)返回的double直接转换为int时,为什么它是2147483647?
我正在阅读一本书中的类型转换和数据类型,但文本没有解释太多。我很迷惑。请解释为什么第二个和第三个表达式会产生这些结果。
答案 0 :(得分:3)
不,因为据我所知,它会截断前32位的所有内容 - 因此它不知道开头的1
(或者更确切地说,最后)。
4294967296 = 0x100000000(十六进制),只取前32位给你零。
编辑:我实际上认为另一个与从浮点到int的特殊转换有关,这与通过long然后是int不同,因为它是对处理器完全不同的类型转换
答案 1 :(得分:2)
Java规范的5.1.3节涵盖了这一点。
http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363
整数缩小只取最低n位,这意味着不考虑符号。事实上,负数可能会变为正数。扩展没有此属性,并将数字签名扩展为更宽的类型。
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
浮点缩小是一个复杂得多的过程,它基本上将数字截断为目标类型中可能的最接近的表示,向零舍入。在这种情况下,触发溢出/下溢规则,将浮点数转换为类型可表示的最大/最小值。
答案 2 :(得分:0)