[譯]浮點數的危害

橘子oly發表於2016-10-24

The Perils of FloatingPoint

by Bruce M. Bush

Copyright (c) 1996 Lahey Computer Systems, Inc. Permission to copy isgranted with acknowledgement of the source.

原文參見  The Perils of Floating Point

[譯]浮點數的危害

By wttttt

@2016.10.24【慶祝這個偉大的程式設計師的節日?233】

如果沒有數字電腦的浮點數能力,許多偉大的程式設計師和科學家們可能不會有近些年的進展。然而,即使對有著多年數學經驗的人而言,一些浮點數的計算結果還是看起來十分奇怪。我將試圖解釋這其中一些奇怪結果的產生原因,並在適當時給出一些建議。

    浮點數表示和計算是不精確的,但是我不認為這對程式設計師而言是十分麻煩的。許多輸入值是測量結果,它們本身就是不精確的,因此關於輸出值的問題不在於是否存在錯誤,而在於錯誤被預料的程度。然而,當你可以在腦海裡計算的結果比比電腦用它的浮點數計算結果更精確時,你就會開始感到懷疑了。  

我使用FORTRAN編寫我的例子,原因如下:

1.   FORTRAN比其他的計算機語言有更多的浮點數計算;

2.   我在Lahey Computer Systems公司工作,它們開發和銷售FORTRAN語言系統。

二進位制浮點數

許多奇怪結果的核心根本都是:計算機的浮點數通常是二進位制的,然而外部表示是十進位制的。我們預計1/3將不會是可精確表示的,但是直覺上似乎.01是可以的。不是這樣的!.01在IEEE單精度表示是10737418/1073741824或近似地0.009999999776482582。你甚至可能沒有注意到這些區別,知道你看到如下所示的程式碼:

REAL X

DATA X/.01/

IF ( X* 100.d0 .NE. 1.0 ) THEN

   PRINT *, 'Many systems print this surprisingresult. '

ELSE

   PRINT *, 'And some may print this.'

ENDIF

十進位制浮點數實現沒有這種奇怪現象。然而,十進位制浮點數實現是很稀少的,因為在數字電腦中二進位制計算要快很多。

不精確性

數字電腦上的浮點數運算的不精確性是天性的。一個32位浮點數的24位元(包括隱藏位元)尾數近似地表示7個重要的十進位制數字。不想連續的實數系統,一個浮點數系統在數字之間時有間隔的。如果一個數字是不可精確表示的,那麼它一定是通過最近的可表示的值來近似的。

因為相同數量的數字被用來表示所有的正常化的數字,所以樣品數量越小,可表示數字的密度越大。比如,在1.0和2.0之間近似有8,388,607個單精度數字,然而1023.0和1024.0之間僅僅有大約8191個單精度數字。

在任意計算上,數學上等價的表示式使用浮點計算可以產生不同值。在如下例子中,Z和Z1將有不同值,因為(1/Y)或者1/7在二進位制浮點數中是不可精確表示的。

REALX, Y, Y1, Z, Z1

DATAX/77777/, Y/7/

Y1 = 1/ Y

Z = X/ Y

Z1 = X* Y1

IF (Z.NE. Z1) PRINT *, 'Not equal!'

END

 

不重要的數字

如下的示例程式碼闡述了一個現象--看起來重要的無意義的數字:

REALA, Y

DATA Y/1000.2/     ! About 7 digits ofprecision in Y

A = Y- 1000.0      ! About 3 significantdigits in result

PRINT*, A          ! Prints 0.200012

END

一個單精度(實數)實體可以最大表示大約7個十進位制精度數字,因此

 

相關文章