3

这是Java中的代码片段:

int i = 1234567890;     
float f = i;    
System.out.println(i - (int)f);

为什么输出不等于0?它执行扩展,因此不应该丢失数据。然后,您只需截断该值。最好的祝福

4

5 回答 5

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
于 2012-10-16T08:44:52.170 回答
2

你的错误在这里:

它执行扩展,因此不应该丢失数据。

这种说法是错误的。扩大并不意味着您不会丢失数据。

Java规范

扩大原始转换不会丢失有关数值整体大小的信息。

将 int 或 long 值转换为 float,或将 long 值转换为 double,可能会导致精度损失- 也就是说,结果可能会丢失值的某些最低有效位。在这种情况下,生成的浮点值将是整数值的正确舍入版本,使用 IEEE 754 舍入到最近模式(第 4.2.4 节)。

强调我的。

规范明确指出,量级不会丢失,但会丢失精度。

扩大这个词不是指数据类型的精度,而是指它的范围。浮点数比整数更宽,因为它们的范围更大。

整数

4 个字节,有符号(二进制补码)。-2,147,483,648 至 2,147,483,647。

漂浮

4 字节,IEEE 754。覆盖范围从 1.40129846432481707e-45 到 3.40282346638528860e+38(正或负)。

如您所见,float具有更大的范围。但是,某些整数不能完全表示为浮点数。这种表示错误导致您的结果与 0 不同。存储在 f 中的实际值是 1234567936。

于 2012-10-16T08:37:50.990 回答
0

扩大可能会失去精度。Anint具有 32 位精度,而 afloat具有 25 位精度(24 位尾数和隐含的最高位)。Java 认为float比 64 位更宽,long恕我直言有点疯狂

由于精度有 8 位差异,误差可能高达 +/-64 左右,因为它将int值四舍五入到最接近的float表示。

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
于 2012-10-16T08:39:27.143 回答
0

你会惊讶地发现,即使这是真的:

(f==(f+1))==true

给定f的是一个足够大的浮点数......

于 2012-10-16T08:40:34.833 回答
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

看到不同。

比较整数浮点数具有更大的值。

于 2012-10-16T08:41:13.980 回答