我陷入由浮点精度导致的测试失败,并试图理解它。
简而言之: Python3 round
根据类型是float还是numpy.float64返回不同的值,尽管我认为float==double==float64
和Python 3 ,NumPy应该四舍五入到偶数。
这里是示例:
npVal = np.float64(435)/100
pyVal = 435/100
print(round(npVal,1)) // 4.4
print(round(pyVal,1)) // 4.3
print(round(np.float64(pyVal),1)) // 4.4
print(round(float(npVal),1)) // 4.3
我了解到4.35和4.4可能无法完全用double表示,但是为什么numpy的回合与Python不同,尽管它们都使用相同的数据类型并指定了相似的函数?我使用显式除法来避免输入舍入错误。
我不确定,4.35的double值是多少还是更少,所以我不能说哪个是(可能是)错误。< / p>
还有一个类似的问题:Strange behavior of numpy.round
有人指出,NumPy“四舍五入到最接近的偶数值”和“行为在Python 2和Python 3之间发生了变化; Python 3的行为与此处的NumPy相同”。
因此,两者应做相同的操作并四舍五入到最接近的偶数值。因此,如果 4.35是精确的浮点数,则4.4将是正确的答案,并且两者都需要返回。
答案 0 :(得分:2)
在IEEE-754基本64位二进制浮点中计算435/100,得出4.3499999999999996447286321199499070644378662109375。
当四舍五入到小数点后一位数字舍入到最接近的十进制数字时,结果应为“ 4.3”。这种情况下的Python舍入似乎是正确的。
对于numpy.round
,documentation指的是numpy.around
。的documentation表示:“由于…在以10的幂进行缩放时引入了错误,结果也可能令人惊讶。”因此,numpy.round
可能没有计算出4.3499999999999996447286326321199499070644378662109375到十进制的正确转换,但宁愿执行64位二进制浮点乘法乘以10,由于浮点舍入而产生的正好为43.5,然后numpy.round
将其舍入为44并将其格式化为“ 4.4”。
总而言之,numpy.round
不是正确的舍入例程。