簡體   English   中英

C#中的Mod:返回錯誤值

[英]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

345227121439310000000000000437 = 48

48 ^ 61 = 3,5951372914138399900210185557119e + 102

3,5951372914138399900210210185557119e + 102437 = 110

但是,使用我的代碼,我得到了以下結果:

http://imageshack.com/a/img537/1309/7l42tc.jpg

對於那些看不到圖像的人,結果是:

val = 337 vf = 6

使用64位雙精度無法准確表示110^1348^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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM