[英]Different Truncation Results When Casting
我在预测我的C代码将如何截断结果时遇到一些困难。 请参阅以下内容:
float fa,fb,fc;
short ia,ib;
fa=160
fb=0.9;
fc=fa*fb;
ia=(short)fc;
ib=(short)(fa*fb);
结果是ia = 144,ib = 143。
我可以理解这两种结果的推理,但我不明白为什么这两种计算的处理方式不同。 任何人都可以推荐我这个行为的定义或解释差异?
编辑:结果使用英特尔酷睿i3-330m上的MS Visual C ++ Express 2010进行编译。 我在同一台机器上的Virtual Box下的gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5)上得到了相同的结果。
允许编译器对fa*fb
这样的子表达使用比分配给像fc
这样的float
变量时使用的精度更高的精度。 所以它是fc=
part,它会稍微改变结果(然后发生在整数截断中产生差异)。
aschepler解释了正在发生的事情的机制,但是你的代码的基本问题是使用一个值,该值在代码中不作为float
存在 ,它以不稳定的方式依赖于其近似值。 如果你想乘以0.9(实际数字0.9 = 0.9f
,而不是浮点值0.9
或0.9f
),你应该乘以9然后除以10,或者忘记浮点类型并使用十进制算术库。
解决问题的一种廉价而肮脏的方法,就像你的例子中的不稳定点被隔离一样,只是添加一个值(通常为0.5),你知道它将大于错误但小于之前的下一个整数的差值截断。
这取决于编译器。 在我的(gcc 4.4.3)中,它为两个表达式产生相同的结果,即-144,可能是因为相同的表达式被优化掉了。
其他人解释了发生的事情。 换句话说,我会说差异可能是因为你的编译器在执行乘法之前在内部将浮点数提升到80位fpu寄存器,然后转换回float或short。
如果你写ib = (short)(float)(fa * fb);
我的假设是真的ib = (short)(float)(fa * fb);
你应该得到与将fc转换为short时相同的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.