提问人:mcu 提问时间:10/25/2015 最后编辑:mcu 更新时间:11/1/2023 访问量:394
使用缩放容差比较浮点数
Using a Scaled Tolerance to Compare Floats
问:
我突然想到,比较浮子的一个好方法是用浮子缩放公差。这是个好主意吗?
此例程需要针对特殊数量(例如 NaN、+/-Inf)进行扩展,但它给出了一个基本概念。
def FloatEq(a, b, ToleranceFactor=1e-6):
if a == b: return True
c = min(abs(a), abs(b))
return(abs(a-b) < (c*ToleranceFactor))
a = 0.000000000001
b = 0.000000000001000000001
print('Straight compare ==', a==b)
print('FloatEq(,,1e-6) ==', FloatEq(a,b))
print('FloatEq(,,1e-10) ==', FloatEq(a,b,1e-10))
输出:
Straight compare == False
FloatEq(,,1e-6) == True
FloatEq(,,1e-10) == False
更新:
一种可能的解决方案,可以处理其中一个操作数为零。它使用固定的、用户可配置的公差,而不是一个因子。
def FloatEq(a, b, ToleranceFactor=1e-6, ToleranceAtZero=None):
if a == b:
return True
elif a==0 or b==0:
c = a if b==0 else b
if ToleranceAtZero is None:
import sys
# Ignoring denormalized numbers for now
ToleranceAtZero = sys.float_info.min
return abs(c) < ToleranceAtZero
else:
c = min(abs(a), abs(b))
return(abs(a-b) < (c*ToleranceFactor))
答:
0赞
Peter Cordes
10/25/2015
#1
这是一个明智的想法,除非您正在比较可能是灾难性取消结果的值(例如,减去两个附近的数字以产生一个非常小、非常不准确的数字)。在这种情况下,我认为您应该根据预取消值的大小来缩放容差。
我不是数值计算/浮点专家。把这些东西做好是很困难的,而且有一个完整的堆栈交换:计算 Science.SE。
一些搜索出现了:https://scicomp.stackexchange.com/questions/3362/relative-comparison-of-floating-point-numbers 有几个关于FP比较的答案。
上一个:C语言中的纬度/经度存储和压缩
下一个:使用缩放容差比较浮点数
评论
if
else
abs
min(abs(a), abs(b))
return
False
1000.0+0.0001 == 1000.0
0.00000001+0.0001 == 0.00000001