[英]Mod in C#: It returns a wrong value
好的,這是我的代碼:
int a, b, c, d;
double v1, v2, v3, vf, val;
a = 110;
b = 13;
c = 437;
d = 61;
v1 = Convert.ToDouble(a);
v2 = Convert.ToDouble(b);
v3 = Convert.ToDouble(d);
val = Math.Pow(v1, v2);
val = val % c;
Console.WriteLine("O valor do primeiro MOD é: {0}", val);
vf = Math.Pow(val, v3);
vf = vf % c;
Console.WriteLine("O valor final é: {0}", vf);
Console.ReadKey();
這就是事情,如果我使用計算器這樣做,我將得到以下結果:
110 ^ 13 = 345227121439310000000000000
345227121439310000000000000 % 437 = 48
48 ^ 61 = 3,5951372914138399900210185557119e + 102
3,5951372914138399900210210185557119e + 102 % 437 = 110
但是,使用我的代碼,我得到了以下結果:
( http://imageshack.com/a/img537/1309/7l42tc.jpg )
對於那些看不到圖像的人,結果是:
val = 337 vf = 6
使用64位雙精度無法准確表示110^13
和48^61
。 數據類型的精度不足以精確地表示這些值。 因為您不能精確地表示您的操作數,所以實際上您執行的運算與您打算執行的運算不同。 一旦無法表示原始操作數,就沒有恢復的希望。
您需要使用足夠精確的類型。 例如, System.Numerics.BigInteger
。
Double無法滿足您的情況。 Double 精確到16位數字 。 您的值分別為26和102位數字。 無法表示的數字會丟失,從而導致精度下降。
您應該使用某種bigint庫:
使用double不起作用的原因是因為double數據類型的精度不足。 大數字(例如110^13
不能精確表示為兩倍-它們會損失很多有效數字。
解決方案是使用可以表示非常大的整數的類型進行計算。
使用BigInteger
如下:
BigInteger a = new BigInteger(110);
BigInteger b = new BigInteger(13);
BigInteger c = new BigInteger(437);
BigInteger val = BigInteger.ModPow(a, b, c);
請注意,有一個特定的方法ModPow()
,它將提高到冪和模數相結合。
還要注意,您可以使用隱式構造函數,該構造函數將int
轉換為BigInteger
,從而將上述代碼簡化為:
BigInteger val = BigInteger.ModPow(110, 13, 437);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.