我正在使用一个名为indata的数组(在堆中,分配了malloc)和一个局部双重的sum.
我写了两个不同的函数来比较indata中的值,并获得不同的结果.最终,我确定这个差异是由于在条件测试中使用表达式的一个函数,另一个函数在相同的条件测试中使用局部变量.我预计这些是等同的.
我的功能A使用:
if (indata[i]+indata[j] > max) hi++;
我的功能B使用:
sum = indata[i]+indata[j]; if (sum>max) hi++;
经过相同的数据集和最大值后,根据我使用的函数,最终得到不同的hi值.我相信功能B是正确的,功能A是误导的.同样地,当我尝试下面的代码片段
sum = indata[i]+indata[j]; if ((indata[i]+indata[j]) != sum) etc.
该条件将评估为真.
虽然我明白浮点数并不一定提供准确的表示,为什么当精确表示变量被评估为一个表达式vs存储在变量中时?建议最佳实践总是在有条件的情况下评估一个双重表达式?谢谢!
解决方法
我怀疑你正在使用32位x86,唯一通用的体系结构要超出精度.在C中,float和double类型的表达式实际上被计算为float_t或double_t,其关系为float和double,反映在FLT_EVAL_METHOD宏中.在x86的情况下,两者都被定义为long double,因为fpu实际上不能以单精度或双精度执行算术. (它有模式位旨在允许,但行为略有错误,因此不能使用.)
分配给float或double类型的对象是强制舍入并摆脱超出精度的一种方法,但是如果您希望将其作为表达式而不作任何操作,也可以添加一个无偿的转换(double).
注意,强制舍入到所需精度不等于以所需精度执行算术;而不是一个四舍五入(在算术中),现在有两个(在算术中,再次降低不必要的精度),而在第一个舍入给出一个精确的中点的情况下,第二个舍入可以进入’错误的方向.这个问题通常被称为双舍入,并且对于某些类型的计算,它使得超出精度显着地比标称精度差.