假設我們有2個常量A
& B
和變量i
,所有64位整數。我們要計算一個簡單常見的算術運算,例如:計算可能溢出的整數運算的最安全和最有效的方法
i * A/B (1)
爲了簡化問題,我們假設變量i
始終處於範圍[INT64_MIN*B/A, INT64_MAX*B/A]
,使運算的最終結果(1)不不溢出(即:適合,範圍[INT64_MIN, INT64_MAX]
)。
此外,i
被假定爲更可能在友好範圍範圍1 = [INT64_MIN/A, INT64_MAX/A]
(即:接近0),然而i
可以是(不容易)在該範圍之外。在第一種情況下,i * A
的平凡整數計算不會溢出(這就是爲什麼我們將範圍稱爲友好的);在後一種情況下,i * A
的平凡整數計算會溢出,導致(1)的計算中出現錯誤的結果。 (1)(其中「最安全」是指:保持正確或至少有一個體面的精度,而「最有效」的意思是:最低平均值的意思是:最安全的和最有效的方式計算時間),提供i
更有可能在友好範圍範圍1。
在現在,目前在代碼中實現的解決方案是以下之一:
(int64_t)((double)A/B * i)
該解決方案是相當安全的(沒有溢出),雖然不準確(精度損失,由於雙尾數53位的限制),相當速度很快,因爲在編譯時預計算雙分區(double)A/B
,因此只能在運行時計算雙倍值。
您可以通過檢查雙重版本的結果來檢測很多情況,但是我不認爲它會捕獲每個案例,因爲您只有64位雙精度型中的53個有效位... –
'(int64_t) ((double)i * A/B)'。你可能會失去精度,因爲你正在處理非常大的值,因爲在你的系統中,double很可能是64位 – sjsam
我的第一個想法是求助於彙編並檢查所有這些CPU標誌。我的第二個想法是我不想這樣做。 –