我意识到np.islcose()函数可用于安全地检查浮点数是否相等。不过,令我感到困扰的是,使用标准的<=运算符会得到各种各样的结果。例如:
circle = Circle(5)
print(circle.area())
#78.53981633974483
cylinder = Cylinder(5, 3)
print(cylinder.volume())
#235.61944901923448
给我
add_to = 0.05
value64 = np.float64(0.3) + add_to*4
value32 = np.float32(0.3) + add_to*4
threshold = 0.5
print('is close?')
print(np.isclose(value64, threshold))
print(np.isclose(value32, threshold))
print('is less than or equals to?')
print(value64 <= threshold)
print(value32 <= threshold)
有人对此有一个明智的解决方法吗?我认为一个选择可能是让python比较运算符重载numpy浮点数,并且(在该函数内)将两个浮点数舍入到它们的小数点后第8位。但这是在速度有些重要并且感觉有点麻烦的情况下进行的。
在此先感谢您的帮助!
答案 0 :(得分:1)
根据此Difference between Python float and numpy float32,python在查看np.float32
和np.float64
的方式上有区别。如果您实际检查value64
和value32
的中间值,则会看到:
value32 = 0.5000000119209289
value64 = 0.5
这说明了为什么print(value32 <= threshold)
的计算结果为假。由于二进制错误,我怀疑四舍五入到小数点后八位是否安全,因为使用value32
时,您将拥有0.50000001
。
您还应该考虑将数字四舍五入的时间绝对是很小的,并且在
的情况下仍必须使用np.float64(0.1) + np.float64(0.2)
,因为它的值为0.30000000000000004
,因此使用>=
或<=
时会出错。如果您使用decimal
库,也会发生此错误。简而言之,有些数字确实无法避免发生某种错误。我知道绕过这个问题的唯一方法就是四舍五入。
我尝试测试一堆带有舍入和不带有舍入的组合,并且它是如此之快,以至于我无法记录10000次迭代中的时间差,因此除非您交易股票或训练神经网络数周,否则我不会认为四舍五入是您无需担心的事情。
如果您担心将数字四舍五入的随意性,我会在一个有效数字之后搜索一个0
长于4的字符串,然后从中删除。
答案 1 :(得分:0)
您可以定义将<
和>
与isclose
组合在一起的函数。
def approx_lte(x, y):
return x <= y or np.isclose(x, y)
def approx_gte(x, y):
return x => y or np.isclose(x, y)
它们类似于<=
和>=
,除了它们还使用np.isclose()
来测试是否相等。