![](/img/trans.png)
[英]What does the C++ standard say about std::vector<int> v1,v2; std::distance(v1.begin(),v2.begin())?
[英]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 60559double
格式匹配。
此外,它說正常算術必須遵循IEC 60559標准:
+
,−
,*
和/
運算符提供IEC 60559加,減,乘和除運算。
它還要求sqrt
遵循IEC 60559:
<math.h>
的sqrt
函數提供IEC 60559平方根操作。
然后繼續描述其他幾個浮點函數的行為,其中大多數你可能對這個問題不感興趣。
最后,它到達math.h
標題,並指定各種數學函數(即sin
, cos
, atan2
, exp
等)應如何處理特殊情況(即asin(±0)
返回±0
, atanh(x)
返回NaN並引發| x |> 1等的“無效”浮點異常。 但它從來沒有確定正常輸入的精確計算,這意味着你不能依賴於產生完全相同計算的所有實現。
所以不,它不要求這些函數在所有實現中表現相同,即使實現都定義了__STDC_IEC_559__
。
這都是從理論的角度來看的。 在實踐中,情況更糟。 CPU通常實現IEC 60559算法,但是可以有不同的舍入模式(因此結果會因計算機而異),編譯器(取決於優化標志)可能會做出一些不嚴格符合標准的假設。浮點運算。
所以在實踐中,它甚至比理論上更嚴格,你很可能會看到兩台計算機在某些時候產生的結果略有不同。
一個真實世界的例子是glibc,即GNU C庫實現。 它們有一個已知的錯誤限制表,用於跨不同CPU 的數學函數 。 如果所有C數學函數都是位精確的,那些表將顯示0個錯誤的ULP。 但他們沒有。 表格顯示其C數學函數確實存在不同的誤差量。 我認為這句話是最有趣的總結:
除了某些函數,如
sqrt
,fma
和rint
其結果通過引用相應的IEEE 754浮點運算完全指定,以及字符串和浮點之間的轉換,GNU C庫的目標不是正確舍入結果。數學圖書館[...]
glibc中唯一具有精確位置的東西是C標准的附件F要求精確到位的東西。 正如你在他們的表中所看到的,大多數事情都沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.