这是Java中的代码片段:
int i = 1234567890;
float f = i;
System.out.println(i - (int)f);
为什么输出不等于0?它执行扩展,因此不应该丢失数据。然后你只是截断值。 最好的问候
答案 0 :(得分:4)
查看差异
int i = 1234567890;
float f = i;
System.out.println(i - f);
System.out.println((int)f);
System.out.println(f);
System.out.println(i-(int)f);
输出:
0.0
1234567936
1.23456794E9
-46
答案 1 :(得分:2)
你的错误在这里:
它执行扩展,因此不应该丢失数据。
这种说法是错误的。扩展并不意味着您不会丢失数据。
扩展原始转换不会丢失有关数值的总幅度的信息。
将int或long值转换为float,或将long值转换为double,可能会导致精度损失 - 也就是说,结果可能会丢失一些最低有效位价值。在这种情况下,使用IEEE 754舍入到最接近模式(第4.2.4节),得到的浮点值将是整数值的正确舍入版本。
强调我的。
规范明确指出幅度不会丢失,但精度可能会丢失。
加宽这个词不是指数据类型的精确度,而是指范围。浮标比整数更宽,因为它们的范围更大。
<强> INT 强>
4个字节,有符号(二进制补码)。 -2,147,483,648至2,147,483,647。
<强>浮强>
4个字节,IEEE 754.涵盖范围从1.40129846432481707e-45到3.40282346638528860e + 38(正或负)。
如您所见,float
的范围更大。但是有些整数不能完全表示为浮点数。此表示错误是导致结果与0不同的原因。存储在f中的实际值为1234567936。
答案 2 :(得分:0)
加宽可能会失去精确度。 int
具有32位精度,其中float
具有25位精度(24位尾数和隐含的顶位)。 Java认为float
要宽于64位long
,这有点疯狂恕我直言
如果精度为8位差异,则将int
值舍入为最接近的float
表示时,误差可高达+/- 64左右。
int err = 0;
for (int i = Integer.MAX_VALUE; i > Integer.MAX_VALUE / 2; i--) {
int err2 = (int) (float) i - i;
if (Math.abs(err2) > err) {
System.out.println(i + ": " + err2);
err = Math.abs(err2);
}
}
打印
... deleted ...
2147483584: 63
2147483456: -64
答案 3 :(得分:0)
你会惊讶地发现即便如此:
(f==(f+1))==true
给定f
是一个足够大的浮点数......
答案 4 :(得分:0)
int i = 1234567890;
float f = i;
System.out.println((int)f);
System.out.println(i);
System.out.println(i - (int)f);
输出是:
1234567936
1234567890
-46
看到差异。
比较整数浮点数具有更大的值。