我的代码很简单,只有1行引起了问题:
np.tan(np.radians(rotation))
我得到的rotation = 45
的预期输出不是1,而是0.9999999999999999。我知道0和9等于1是一吨,但是,在我的用例中,似乎肯定会在迭代中建立起来的东西。
是什么导致浮点错误:np.tan
或np.radians
,以及如何在不考虑浮点错误的情况下正确显示问题函数?
我应该澄清一下,我对浮点错误很熟悉。我担心的是,随着该数字的增加,增加和比较,1e-6错误突然变成一个明显的问题。我通常可以安全地忽略浮点问题,但是现在我更加担心错误的累积。我想减少发生此类错误的可能性。
我当前的解决方案是将四舍五入到小数点后8位,因为这很有可能。这是一个临时解决方案,因为我更喜欢一种绕过IEEE十进制表示形式的方法。
答案 0 :(得分:1)
是什么导致浮点错误:
np.tan
或np.radians
,以及如何在不考虑浮点错误的情况下正确显示问题函数?
这两个函数均会产生舍入错误,因为在任何情况下都不能以浮点表示精确的结果。
我当前的解决方案是将四舍五入到小数点后8位,因为这很有可能。这是一个临时解决方案,因为我更喜欢一种绕过IEEE十进制表示形式的方法。
该问题与十进制表示形式无关,这将在您上面提到的确切情况之外给出更差的结果,例如
>>> np.tan(np.radians(60))
1.7320508075688767
>>> round(np.tan(np.radians(60)), 8)
1.73205081
>>> np.sqrt(3) # sqrt is correctly rounded, so this is the closest float to the true result
1.7320508075688772
如果您绝对需要比上面代码中的15位小数位数更高的精度,则可以使用gmpy2之类的任意精度库。
答案 1 :(得分:0)
在这里看看:https://docs.scipy.org/doc/numpy/user/basics.types.html。
numpy中的标准dtype不会超过64位精度。从文档中:
请注意,即使
np.longdouble
比python提供更高的精度 浮点数,很容易失去额外的精度,因为python通常 强制值通过浮点型。例如,%
格式 运算符要求将其参数转换为标准python 类型,因此无法保持扩展的精度 即使要求许多小数位。测试可能有用 您的代码的值为1 + np.finfo(np.longdouble).eps
。
您可以使用np.longdouble
来提高精度,但这取决于平台
在spyder中(Windows):
np.finfo(np.longdouble).eps #same precision as float
>> 2.220446049250313e-16
np.finfo(np.longdouble).precision
>> 15
在Google colab中:
np.finfo(np.longdouble).eps #larger precision
>> 1.084202172485504434e-19
np.finfo(np.longdouble).precision
>> 18
print(np.tan(np.radians(45, dtype=np.float), dtype=np.float) - 1)
print(np.tan(np.radians(45, dtype=np.longfloat), dtype=np.longfloat) - 1)
>> -1.1102230246251565e-16
0.0