繁体   English   中英

浮点算术错误

[英]Floating Point Arithmetic error

我正在使用以下函数来近似函数的导数:

def prime_x(f, x, h):

    if not f(x+h) == f(x) and not h == 0.0: 
        return (f(x+h) - f(x)) / h
    else:
        raise PrecisionError

作为测试,我将f传递为fxx传递为3.0。 其中fx是:

def fx(x):

    import math
    return math.exp(x)*math.sin(x)

其中exp(x)*(sin(x)+cos(x))为导数。 现在,根据谷歌和我的计算器

exp(3)*(sin(3)+cos(3)) = -17.050059

到现在为止还挺好。 但是,当我决定与小值测试功能h我有以下几点:

print prime_x(fx, 3.0, 10**-5)
-17.0502585578
print prime_x(fx, 3.0, 10**-10)
-17.0500591423
 print prime_x(fx, 3.0, 10**-12)
-17.0512493014
print prime_x(fx, 3.0, 10**-13)
-17.0352620898
print prime_x(fx, 3.0, 10**-16)
__main__.PrecisionError: Mantissa is 16 digits

当h减小时(某个点之后),为什么误差会增加? 我期待相反,直到f(x+h)等于f(x)

浮点运算(以及整数运算和定点运算)具有一定的粒度:值只能改变一定的步长。 对于IEEE-754 64位二进制格式,该步长约为该值的2 -52倍(约2.22•10 -16 )。 这对于物理测量来说非常小。

) is not very large compared to the step size. 但是,当你使h非常小时,f( x )和f( x + )之间的差异与步长相比并不是很大。 差异只能是步长的整数倍。

. 当导数为d时 ,f( x )的变化约为h · ) as well as possible in the floating-point format, the measured value of their difference must be a multiple of the step size s , so it must be round( h / s )• s , where round( y ) is y rounded to the nearest integer. 即使您以浮点格式计算f( x )和f( x + ),它们的差值的测量值也必须是步长s的倍数,因此它必须是圆的( h / s)•s,其中轮(Y)y取整到最接近的整数。 / s is smaller, so the effect of rounding it to an integer is relatively larger. 显然,当你使h小时h / s越小,因此将其舍入为整数的效果相对更大。

另一种观察方式是,对于给定的f( x ),在计算f( x )周围的值时存在一定量的误差。 )–f( x ) gets smaller, but the error stays the same. 当你使h小时 ,f( x + )-f( x )变小,但误差保持不变。 因此,误差相对于h增加。

当您减去两个几乎相同的数字时,结果的精度远低于任何一个输入。 这降低了整体结果的精度。

假设你有以下两个数字,好到15个小数位:

  1.000000000000001
- 1.000000000000000
= 0.000000000000001

看看发生了什么? 结果只有一个好数字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM