我尝试了以下代码.
class test { public static void main(String arf[]) { System.out.println((int)2147483648.0); System.out.println((int)2147483648L); } }
…其中2147483647是int的最大值.
输出为:
2147483647 -2147483648
当float转换为int时,它的小数部分被删除.所以,(int)2147483648.0也应该等于-2147483648.
任何人都可以向我解释为什么2147483648.0被转换为2147483647?
解决方法
将其截断为最高int值的原因描述为in the language specification作为缩小转换.
In the first step,the floating-point number is converted either to a long,if T is long,or to an int,if T is byte,short,char,or
int,as follows:
If the floating-point number is NaN (§4.2.3),the result of the first step of the conversion is an int or long 0.
Otherwise,if the floating-point number is not an infinity,the floating-point value is rounded to an integer value V,rounding
toward zero using IEEE 754 round-toward-zero mode (§4.2.3). Then
there are two cases:If T is long,and this integer value can be represented as a long,then the result of the first step is the long value V.
Otherwise,if this integer value can be represented as an int,then the result of the first step is the int value V.
这里的相关部分是值将向零.只要浮点值(或长)高于Integer.MAX_VALUE,则转换为int将导致其最高值.对于低于Integer.MIN_VALUE的值也是如此.
如果你使用(int)-214783649L;它会突然变成214783647!为什么这种情况也在JLS中解释,重点是我的:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits,where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value,this may cause the sign of the resulting value to differ from the sign of the input value.
该值在二进制中的长时间表示,表示32位截止值,如下所示:
1111 1111 1111 1111 1111 1111 1111 1111 | 0111 1111 1111 1111 1111 1111 1111 1111
当转换发生时,前32位被丢弃,留下最高可能的int.
反向是正的长 – 高32位包含所有1在转换时被丢弃.
完整结构如下,管道再次表示32位标记:
1111 1111 1111 1111 1111 1111 1111 1111 | 1000 0000 0000 0000 0000 0000 0000 0000