首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原始值转换

问原始值转换
EN

Stack Overflow用户
提问于 2012-10-16 16:36:07
回答 5查看 1.3K关注 0票数 3

这是Java中的代码片段:

代码语言:javascript
复制
int i = 1234567890;     
float f = i;    
System.out.println(i - (int)f);

为什么输出不等于0?它执行扩展,所以它不应该丢失数据。然后,您只需截断该值。诚挚的问候

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-10-16 16:44:52

看到其中的区别

代码语言:javascript
复制
 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);

输出:

代码语言:javascript
复制
0.0

1234567936

1.23456794E9

-46
票数 4
EN

Stack Overflow用户

发布于 2012-10-16 16:37:51

你的错误在这里:

它执行加宽,所以它不应该丢失数据。

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

从Java specification

整体加宽基元转换不会丢失有关数值的总体大小的信息。

如果将整型或长整型值转换为浮点型,或者将长整型值转换为双精度型,则可能会导致精度丢失-也就是说,结果可能会丢失该值的一些最低有效位。在这种情况下,产生的浮点值将是整数值的正确舍入版本,使用IEEE 754舍入到最近的模式(§4.2.4)。

重点是我的。

该规范清楚地指出,震级不会丢失,但精度可能会丢失。

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

int

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

float

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

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

票数 2
EN

Stack Overflow用户

发布于 2012-10-16 16:39:27

加宽区域可能会失去精度。int的精度为32位,而float的精度为25位(一个24位的尾数和一个隐含的顶位)。Java认为float比64位long更宽,这有点疯狂。

如果精度相差8位,则在将int值舍入到最接近的float表示形式时,误差最高可达+/-64。

代码语言:javascript
复制
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);
    }
}

打印

代码语言:javascript
复制
... deleted ...
2147483584: 63
2147483456: -64
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12910602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档