簡體   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