当[int]=[float]+;[int](Obj-C,iOS?)
在这种情况下:当[int]=[float]+;[int](Obj-C,iOS?),ios,objective-c,rounding,floating-point-precision,Ios,Objective C,Rounding,Floating Point Precision,在这种情况下: float a = 0.99999f; int b = 1000; int c = a + b; 结果c=1001。我发现这是因为b被转换为float(特定于iOS),然后a+b没有足够的精度满足1000.9999,并且(为什么?)被四舍五入到更高的值。如果a为0.999f我们得到c=1000-理论上正确的行为 所以我的问题是为什么浮点数被舍入到更高的值?该行为(或约定)在何处描述 我在iPhone模拟器Apple LLVM 4.2编译器上对此进行了测试。原因是,当您添加100
float a = 0.99999f;
int b = 1000;
int c = a + b;
结果c=1001
。我发现这是因为b
被转换为float(特定于iOS),然后a+b
没有足够的精度满足1000.9999
,并且(为什么?)被四舍五入到更高的值。如果a
为0.999f
我们得到c=1000
-理论上正确的行为
所以我的问题是为什么浮点数被舍入到更高的值?该行为(或约定)在何处描述
我在iPhone模拟器Apple LLVM 4.2编译器上对此进行了测试。原因是,当您添加1000时,总共得到8位小数精度,但IEEE浮点仅支持7位。在
int c=a+b
中,整数b
首先转换为浮点,然后转换为2位浮点
数字被添加,结果被截断为整数
默认的浮点舍入模式是FE\u TONEAREST
,这意味着结果
附加值
0.99999f + 1000f
是可表示为浮点数的最接近的编号,即编号1001f
。然后将该浮点值截断为整数c=1001
如果您更改舍入模式
#include <fenv.h>
fesetround(FE_DOWNWARD);
#包括
fesetround(feu向下);
然后加法的结果向下四舍五入(大约
1000.99993f
),你会得到c=1000
这里我得到1000。我的错误,各位<代码a=0.9999FintC=(int)a+b代码>它给了我1000
,即使a
是0.9999999f
@holex-Try(int)(a+b)
@HotLicks,我已经试过了。但是为什么这个数字是四舍五入的呢?边远的数字应该被截断(比如在float
->int
转换中)。@brigadir-本质上,总和的计算精度要高得多,可能会产生1000.999932的结果。但这不能表示为32位浮点。因此,两个最接近的“法定”值可能是1000.9999843和1001.0000017。在默认舍入模式下,FP单位选择后者,因为它更接近“真实”答案。接近,但不完全正确。表示浮点加法结果的最近值类似于1001.000032(从空气中提取一个数字),因此结果将四舍五入到该值。然后,根据标准C规则,在浮点->整数转换时,该数字被截断为1001。@HotLicks:我不太明白。为什么最接近0.99999+1000的浮点数应该是1001.000032而不是1001?1001可以表示为浮点数,比1001.000032更接近1000.99999。(在给出答案之前,我也在调试器中对此进行了验证。)-也许我完全遗漏了什么?是的,我想你是对的——小整数在IEEE浮点中完全可以表示。但需要强调的是,舍入是将浮点值转换为最接近的IEEE表示形式,而不是舍入为整数。本质上,四舍五入是1001.00000,而不是1001。@HotLicks:我明白你的意思。这就是我所说的“可以表示为浮点数的最接近的数字,即数字1001f
”。所以“float”指的是C类型的float,即IEEE的float。我稍微修改了答案,以强调截断为int是一个单独的步骤。谢谢你的反馈!