2009-11-07 108 views
3

昨天我問了一個浮點問題,我又有一個問題。我正在做一些計算,我使用math.h(C語言)的正弦,餘弦和正切函數的結果。浮點再次

其中一位開發者嘀咕道,你必須小心這些函數的返回值,我不應該對gcc數學函數的返回值做出假設。我不想開始討論,但我真的很想知道在使用標準數學函數進行計算時需要注意什麼。

X

+1

您已經成功創建了兩個帳戶。您之前的問題是使用http://stackoverflow.com/users/205441/xofo問的。電子郵件[email protected]關於讓他們合併。 – ChrisF 2009-11-07 21:54:30

+0

不完全回答你的問題,但如果你使用gcc,你可以嘗試使用-mfpmath = sse標誌來減少一些浮點錯誤。 – int3 2009-11-08 10:23:36

回答

3

你不應該假定返回的值將是高程度的不同的編譯器/ STDLIB版本之間的精確一致。

就是這樣。

+0

這是我記得被說過的。所以如果我想要更高的準確性,我是否會使用另一個數學庫,以及哪一個? x – Xofo 2009-11-07 21:59:30

+1

如果您想確保不同的編譯器提供完全相同的值,那麼您應該推出自己的sin/cos/tan函數,而不是使用供應商提供的stdlib函數。或者使用這樣做的第三方庫。自然,這些函數不能調用其他stdlib例程。 或者,您可以生成一組存儲爲數據文件的觸發表,並且您的sin/trig/cos例程將作爲查找。 我會問,這是否真的有必要嗎?這是我過去不得不做的事情,但肯定不常見。 – 2009-11-07 22:26:14

+1

滾動你自己的點很少。 Netlib是相當標準的http://www.netlib.org/fdlibm/ – 2009-11-07 22:37:58

0

問題不在於標準的數學函數,而在於浮點運算的性質。

非常短的版本:不要比較兩個浮點數的相等性,即使有明顯的瑣碎身份,如10 == 10/3.0 * 3.0tan(x) == sin(x)/cos(x)

1

浮點很簡單。請記住,所有浮點運算和函數都存在不確定性組件。它通常被建模爲隨機的,儘管它通常不是,但如果你把它看作隨機的,你將會成功地理解你自己的代碼。例如:

a = a/3 * 3;

這應該被視爲好像它是:

A =(A/3 + ERROR1)* 3 +誤差2;

如果你想估計錯誤的大小,你需要挖掘每個操作/功能來找出。不同的編譯器,參數選擇等會產生不同的值。例如,具有5位精度的系統上的0.09-0.089999會產生-0.000001和0.000001之間的某個錯誤。這個錯誤的大小與實際結果相當。

如果你想學習如何做到浮動點的精確和可行,那麼這是一個由它自己研究。

+0

它不僅是隨機的,但你的答案確實沒有提供有價值的信息。 – rlbond 2009-11-07 22:38:26

+0

如果你學習數值分析,這就是大學教授的方法,它基本上是計算機上浮點計算的數學。音頻工程師不會將其稱爲隨機值,他們會將其稱爲「噪音」,但這是相同的想法。 我的文章提供了使程序員能夠理解的信息,浮點代碼中發生錯誤的位置以及錯誤的大小。通過將隨機值的大小綁定到編譯器的選擇上,原始問題得到了回答。 – 2009-11-08 09:53:25

+1

在IEEE-754環境中,沒有關於浮點的隨機事件。浮點不是黑魔法。舍入的存在並不意味着非確定性。 – 2009-11-09 17:51:32

3

例如,您不應該期望sin(PI/6)等於cos(PI/3)。即使x處於sin域,你也不應該指望asin(sin(x))等於x。他們會接近,但可能並不平等。

0

同意所有說你不應該比較平等的答覆。你可以做什麼,但是,是檢查的數字足夠接近,就像這樣:

if (abs(numberA - numberB) < CLOSE_ENOUGH) 
{ 
    // Equal for all intents and purposes 
} 

哪裏CLOSE_ENOUGH一些適當小浮點值。