第五章:数学运算-math:数学函数-比较

5.4.3 比较
涉及浮点值的比较很容易出错,每一步计算都可能由于数值表示而引入误差。isclose()函数使用一种稳定的算法来尽可能减少这些误差,同时完成相对和绝对比较。所用的公式等价于:
abs(a-b) <= max(rel_tol * max(abs(a)mabs(b)),abs_tol)
默认地,isclose()会完成相对比较,容差被设置为1e-09,这表示两个值之差必须小于或等于1e-09乘以a和b中较大的绝对值。向isclose()传入关键字参数rel_tol可以改变这个容差。在这个例子中,值之间的差距必须在10%以内。

import math

INPUTS = [
    (1000,900,0.1),
    (100,90,0.1),
    (10,9,0.1),
    (1,0.9,0.1),
    (0.1,0.09,0.1),
    ]

print('{:^8}{:^8}{:^8}{:^8}{:^8}{:^8}'.format(
    'a','b','rel_tol','abs(a-b)','tolerance','close'
    ))

print('{:-^8} {:-^8} {:-^8} {:-^8} {:-^8} {:-^8}'.format(
    '-','-','-','-','-','-'),)

fmt = '{:8.2f}{:8.2f}{:8.2f}{:8.2f}{:8.2f}{!s:>8}'

for a,b,rel_tol in INPUTS:
    close = math.isclose(a,b,rel_tol=rel_tol)
    tolerance = rel_tol * max(abs(a),abs(b))
    abs_diff = abs(a - b)
    print(fmt.format(a,b,rel_tol,abs_diff,tolerance,close))

0.1和0.09之间的比较失败,因为误差表示0.1。
运行结果:
在这里插入图片描述
要使用一个固定或“绝对”容差,可以传入abs_tol而不是rel_tol。

import math

INPUTS = [
    (1.0,1.0 + 1e-07,1e-08),
    (1.0,1.0 + 1e-08,1e-08),
    (1.0,1.0 + 1e-09,1e-08),
    ]

print('{:^8} {:^11} {:^8} {:^10} {:^8}'.format(
    'a','b','abs_tol','abs(a-b)','close'
    ))

print('{:-^8} {:-^11} {:-^8} {:-^10} {:-^8}'.format(
    '-','-','-','-','-'
    ),)

for a,b,abs_tol in INPUTS:
    close = math.isclose(a,b,abs_tol=abs_tol)
    abs_diff = abs(a - b)
    print('{:8.2f}{:11}{:8}{:0.9f}{!s:>8}'.format(
        a,b,abs_tol,abs_diff,close))

对于绝对容差,输入值之差必须小于给定的容差。
运行结果:
在这里插入图片描述
nan和inf是特殊情况。

import math

print('nan,nan:',math.isclose(math.nan,math.nan))
print('nan,1.0:',math.isclose(math.nan,1.0))
print('inf,inf:',math.isclose(math.inf,math.inf))
print('inf,1.0:',math.isclose(math.inf,1.0))

nan不接近任何值,包括它自身。inf只接近它自身。
运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43193719/article/details/88076236
今日推荐