讓,x
是一個整數,y = x * x
。全角度的C++ sqrt函數精度
那麼保證sqrt(y) == x
?
例如,我可以肯定的是sqrt(25)
或sqrt(25.0)
將返回5.0
,不5.0000000003
或4.999999998
?
讓,x
是一個整數,y = x * x
。全角度的C++ sqrt函數精度
那麼保證sqrt(y) == x
?
例如,我可以肯定的是sqrt(25)
或sqrt(25.0)
將返回5.0
,不5.0000000003
或4.999999998
?
不,你不能保證。對於適合浮點類型尾數的動態範圍的整數及其正方形(對於典型的C/C++ double
,爲2^53),您可能確定,但不一定能保證。
您應該避免浮點值和精確值之間的等值比較,特別是精確的整數值。浮點舍入模式和其他這樣的事情可以真正阻礙你。
您可能希望使用「比較範圍」來接受「近似相等」的結果,或者用整數重新計算算法。有多個StackOverflow問題涉及浮點相等比較。我建議你搜索它們並閱讀。
對於某一類的問題,我在這裏寫了一個替代的解決方案: Find n-th root of all numbers within an interval
該解決方案採取不同的辦法不是依靠棘手的浮點運算。
符合IEEE-754標準的允許執行基本操作錯誤(其中sqrt
爲示例)的實現要求正確舍入值。
這意味着錯誤將小於1/2 ULP(最後一個單位)或基本上儘可能接近實際答案。
要回答你的問題,如果實際的答案完全可以由double
表示,那麼你會得到確切的答案。
注意:這不是由C++標準保證的,而是由IEEE-754標準保證的,這對大多數人來說可能不是問題。
最終,一個簡單的測試應該爲你的目的就足夠了:
for(int i = 0; i < (int)std::sqrt(std::numeric_limits<int>::max()); i++)
{
assert((int)(double)i == i);//Ensure exactly representable, because why not
assert(std::sqrt((double)i*i) == i);
}
如果通過,我看不出有任何理由擔心。
你應該可以很容易地蠻力搜索所有的值,最多2^26,但我相信答案是肯定的。在那之後,沒有。
用於平方根的數位教科書算法用餘數== 0結束,從而給出確切的結果。然後,如果浮點庫聲明ieee-754符合性,它也會通過任何其他方式給出這個值。
如果5不能完全代表,它怎麼可能?最好你可以希望的是它截斷爲5. – chris
由於5是一個整數,它不應該完全表示嗎?我在某處讀取double可以精確地存儲整數範圍內的值。 –
@RafiKamal:IEEE-754 64位雙精度浮點數可以準確地表示32位有符號和無符號整數的整個範圍而不會丟失。這隻在那種情況下支配類型轉換。它不管理計算'sqrt(x)'的浮點庫的精度。 –