1. 程式人生 > 其它 >【C++】浮點數運算誤差

【C++】浮點數運算誤差

問題的出現

使用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 不為質數時,我們可以使用「擴充套件歐幾里得演算法」求出乘法逆元。