【C++】浮點數運算誤差
阿新 • • 發佈:2021-04-26
問題的出現
使用double與int型資料進行相同的運算過程:
int main() {
int mod = 1e9 + 7;
double a = pow(13094024580916, 9);
double b = 2;
cout << int(fmod(a / b, mod)) << endl;
long long r = 1;
for (int i = 0; i < 9; i++)
{
r *= 13094024580916 % mod;
r %= mod;
}
cout << r / 2 << endl;
return 0 ;
}
會得到不同的運算結果:
演算法題中常常遇到大數運算,取模作為結果的情況,這種情況採用浮點數型別計算就很容易得到錯誤的結果,而中間計算結果又會超出整型資料的儲存範圍,要怎麼解決呢?
參考leetcode No1830的題解,使用乘法逆元,將問題進行轉換:
兩數相除+取模 → 兩數相乘+取模 → 兩數取模+相乘
這樣就可以避免出現較大的中間結果了。
乘法逆元
定義
計算
當 mm 為質數時,一種簡單的方法是使用「費馬小定理」,即
那麼有
至於如何快速求解 冪運算+取模:
// 快速冪,用來計算 x^y mod m
int quickmul(int x, int y) {
int ret = 1, mul = x;
while (y) {
if (y & 1) {
ret = (LL)ret * mul % mod;
}
mul = (LL)mul * mul % mod;
y >>= 1;
}
return ret;
}
作者:LeetCode-Solution
連結:https://leetcode-cn.com/problems/minimum-number-of-operations- to-make-string-sorted/solution/shi-zi-fu-chuan-you-xu-de-zui-shao-cao-z-qgra/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
當 mm 不為質數時,我們可以使用「擴充套件歐幾里得演算法」求出乘法逆元。