我很難弄清楚如何處理我遇到的問題。 作爲一個複雜公式的一部分,我需要計算一個可以快速溢出兩倍的部分,即結果達到〜1.59 * 10 ^(1331)(用mathematica計算)。 當然這超出了雙倍的範圍。然後我想用long double,在我的linux系統上用gcc 4.6.3
是16byte。使用GMP從公式計算非常大的整數
1)雙精度(8字節)的可能範圍可達10 ^(308)。我是否正確地說,長雙重然後增加實際精確度,但不是值的可能數字範圍?我記得我聽說它可以是或者,取決於系統和編譯器。真的嗎 ?至少我仍然拿到NaN,當我嘗試用長雙倍來計算我的數值時。
2.)當時我正在尋找一種方法來實際計算這些結果,並且我找到了GNU gmp
。我聽說你可以代表非常大的整數,我認爲這可能有幫助。然而,閱讀文檔,似乎與
mpz_t x;
mpz_init(x);
mpz_set_*(x,#);
我可以賦值gmp
整數數據類型,但爲了做到這一點,我可以「唯一」選擇指派通過內置表示的值像double或(u/s)int等數據類型。所有我發現如何分配真正巨大的數字是使用mpz_set_str()
來分配字符串中的數字。 我該如何分配一個複雜計算結果的數字? 簡單地說,公式是這樣的:
long double res1,res2=0.0;
int a,b;
a=780;
b=741;
float d,d1,o,s; // can be values in [0.01,100]
res1=(2*(pow(b,2)*pow(E,b*(o + s))*(pow(d1,2) + pow(E,a*s)*(-1 + pow(E,a*o)) + pow(d,2)*(-1 + pow(E,a*s))) + pow(a,2)*pow(E,a*(o + s))*(pow(E,b*s)*(pow(E,b*o) + (-1 + d)*(1 + d + b*o)) + (-d + d1)*(d + d1 + b*o + b*d*s)) - a*b*(pow(d1,2)*(pow(E,a*(o + s)) + pow(E,b*(o + s))) + pow(E,a*o + (a + b)*s)*(-2 + 2*pow(E,b*o) - b*o) + d1*pow(E,a*s)*(-pow(E,b*o) + pow(E,a*o)*(1 + b*o)) + pow(d,2)*pow(E,a*s)*(-pow(E,b*o) + pow(E,b*(o + s)) + pow(E,a*o)*(-1 + pow(E,b*s) - b*s)) + d*(-(d1*pow(E,b*(o + s))) + (1 + d1)*pow(E,b*o + a*s) - pow(E,a*s + b*(o + s)) + pow(E,b*s + a*(o + s))*(1 + b*o) + pow(E,a*(o + s))*(-1 - b*o + b*d1*s)))))......;
RES2也將是這樣的,而且我到底需要計算RES1/RES2,這通常成爲一個非常小的數目。
我在考慮將公式拆分並向mpg_z添加條件以避免每個術語超出雙倍範圍,但由於公式太長且複雜,因此幾乎不可能。
因此,總之,問題是,我的中間結果會變得如此之大以至於沒有數據類型能夠存儲它們,所以我不能將它分配給mpz並擺脫此問題。
我知道我想計算一個double值,並且實際使用整數mpz_t。據我所知,這是存儲這種大數據的唯一方法,因爲mpf_t只能處理float類型。說實話,我的身邊仍然有關於gmp
中的表示的混淆。
任何想法如何解決這個問題?
考慮使用所有mpz_t變量。丟失整數變量(在我看到的代碼部分中被提升爲雙精度),無論如何你都無法獲得任何東西。從你的函數的一開始就做一切mpz_t。順便說一句你想做什麼? –
它看起來像你沒有做整數算術,所以我會堅持使用mpf_t並使用gmp提供的浮點運算來實現整個公式。 – mwv
這是理論種羣遺傳學,我試圖計算給定任意人口統計分段函數的內胚乳時間的瞬間 – user1841373