簡體   English   中英

標准對於std :: pow,std :: log等cmath函數有什么看法?

[英]What does standard say about cmath functions like std::pow, std::log etc?

標准是否保證函數在所有實現中返回完全相同的結果?

例如pow(float,float)用於32位IEEE浮點數的pow(float,float) 如果傳入相同的兩個浮點數,則所有實現的結果是否相同?

或者是否有一些靈活性,標准允許根據用於實施pow的算法的微小差異?

不,C ++標准不要求cmath函數的結果在所有實現中都是相同的。 對於初學者,您可能無法獲得IEEE-754 / IEC 60559浮點運算。

也就是說,如果一個實現使用IEC 60559並定義__STDC_IEC_559__ ,那么它必須遵守C標准的附錄F(是的,你的問題是關於C ++,但是C ++標准遵循C標准的C標准,如math.h )。 附件F規定:

  • float類型符合IEC 60559單一格式。
  • double類型符合IEC 60559雙重格式。
  • long double類型與IEC 60559擴展格式匹配,否則與非IEC 60559擴展格式匹配,否則與IEC 60559 double格式匹配。

此外,它說正常算術必須遵循IEC 60559標准:

  • +*/運算符提供IEC 60559加,減,乘和除運算。

它還要求sqrt遵循IEC 60559:

  • <math.h>sqrt函數提供IEC 60559平方根操作。

然后繼續描述其他幾個浮點函數的行為,其中大多數你可能對這個問題不感興趣。

最后,它到達math.h標題,並指定各種數學函數(即sincosatan2exp等)應如何處理特殊情況(即asin(±0)返回±0atanh(x)返回NaN並引發| x |> 1等的“無效”浮點異常。 但它從來沒有確定正常輸入的精確計算,這意味着你不能依賴於產生完全相同計算的所有實現。

所以不,它不要求這些函數在所有實現中表現相同,即使實現都定義了__STDC_IEC_559__


這都是從理論的角度來看的。 在實踐中,情況更糟。 CPU通常實現IEC 60559算法,但是可以有不同的舍入模式(因此結果會因計算機而異),編譯器(取決於優化標志)可能會做出一些不嚴格符合標准的假設。浮點運算。

所以在實踐中,它甚至比理論上更嚴格,你很可能會看到兩台計算機在某些時候產生的結果略有不同。


一個真實世界的例子是glibc,即GNU C庫實現。 它們有一個已知的錯誤限制表,用於跨不同CPU 的數學函數 如果所有C數學函數都是位精確的,那些表將顯示0個錯誤的ULP。 但他們沒有。 表格顯示其C數學函數確實存在不同的誤差量。 我認為這句話是最有趣的總結:

除了某些函數,如sqrtfmarint其結果通過引用相應的IEEE 754浮點運算完全指定,以及字符串和浮點之間的轉換,GNU C庫的目標不是正確舍入結果。數學圖書館[...]

glibc中唯一具有精確位置的東西是C標准的附件F要求精確到位的東西。 正如你在他們的表中所看到的,大多數事情都沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM