我试图理解Java中的类型转换。我已经读过long
通过使用int
的范围减少的模数转换为int
而float
通过删除小数部分转换为int
。
我尝试了以下代码。
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
?
答案 0 :(得分:12)
2147483648.0实际上是2 31 ,而int
的最大值是2 31 -1。因此,该浮点值实际上是一个值太高而不适合的值。
它将其截断为最高int值的原因被in the language specification描述为缩小转化。
- 醇>
在第一步中,如果T为long,浮点数将转换为long,如果T为byte,short,char或者,则转换为int int,如下:
如果浮点数为NaN(§4.2.3),则转换的第一步结果为int或long 0。
否则,如果浮点数不是无穷大,则浮点值将四舍五入为整数值V,舍入 使用IEEE 754向往零模式(§4.2.3)向零。然后 有两种情况:
如果T很长,并且此整数值可以表示为long,则第一步的结果是长值V。
否则,如果此整数值可以表示为int,则第一步的结果是int值V.
此处的相关部分是值向零舍入。只要浮点值(或长)高于Integer.MAX_VALUE
,转换为int
将导致其最高值。对于低于Integer.MIN_VALUE
的值也是如此。
如果你使用(int)-214783649L
,会发生一些奇怪的事情;它会突然变成214783647!为什么会发生这种情况也在JLS中解释,强调我的:
将有符号整数缩小转换为整数类型T只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数。除了可能的丢失有关数值大小的信息,这可能会导致结果值的符号与输入值的符号不同。
该值的二进制长表示,表示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
答案 1 :(得分:8)
无论您提供哪个更大的值(而不是最大值)作为SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean logged_in = sharedPreferences.getBoolean("logged_in", false);
if (logged_in) {
startActivity(new Intent(MainActivity.this, YourActivity.class);
} else {
startActivity(new Intent(MainActivity.this, LogIn.class);
}
值,它都会将(拟合)减少到MainActivity.this
最大值,即{{ 1}}
float
编辑:
java中的long值范围是int
,其中2147483647
因此,如果您的long值大于/小于 System.out.println((int)2147483699.0); //2147483647
System.out.println((int)3147483699.0); //2147483647
的值,则转换永远不会准确。
答案 2 :(得分:3)
编译器是 smartass here 。如果仔细观察字节代码,可以看到编译器正在将float值替换为Integer.MAX_VALUE。
所以,就像 Suresh 所说的那样,任何超过2147483647.0的浮点值都会被2147483647取代。
代码:
public static void main(String arf[]) {
int i = (int) 2147483649121.0f;
System.out.println(i);
System.out.println((int) 2147483648L);
}
字节代码:
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: ldc #16 // HERE : int 2147483647
2: istore_1
3: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;
6: iload_1
7: invokevirtual #23 // Method java/io/PrintStream.println:(I)V
10: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;
13: ldc #29 // int -2147483648
15: invokevirtual #23 // Method java/io/PrintStream.println:(I)V
18: return
答案 3 :(得分:0)
任何大于2147483647
的整数都会导致溢出。在这种情况下,任何赋值或转换都会产生负最大值int
-
look(int)2147483699L)也产生-2147483647
System.out.println((int)2147483699L);
答案 4 :(得分:0)
int无法显示小数。 因此,在转换时,浮点数省略了小数点,仅表示绝对数。 这种方法是窄浇铸。