C# 4.0 大數的運算,BigInteger

世紀緣發表於2016-10-15

引用: 


前段時間,有個同事說

30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000001

是個質數。

直覺告訴我,光是在中間加幾個0,在後面加個1,估計不是質數。

有很多面試題,都會要面試者去做一些關於大數的運算,例如在這裡就有判斷上面這個數是不是質數的情況。

 

很明顯,Integer ,Long都是不能來處理如此巨大的數的。

在.net framework 4.0中,System.Numerics.dll 中提供了BigInteger 類。使用這個類可以很方便的解決這個問題。

判斷n是質數的方法:

1:如果是偶數,肯定不是質數

2:如果能夠被小於或等於Sqrt(n) 的數除盡,則不是質數。

程式碼如下:

private static bool IsPrime()
{
    string largeNumber = @"30000000000000000000000...000000001”;
    BigInteger bigInteger = BigInteger.Parse(largeNumber);
    if (bigInteger.IsEven)
    {
        return false;
    }
    for (BigInteger bi = 3; BigInteger.Pow(bi, 2) <= bigInteger; bi += 2)
    {
        if (bigInteger % bi == 0)
        {
            return false;
        }
    }
    return true;
}

本來for 迴圈中的程式碼應該是

for (BigInteger bi = 3; bi <= BigInteger.Sqrt(bigInteger); bi += 2)
{
    if (bigInteger % bi == 0)
    {
        return false;
    }
}

 

可惜的是BigInteger 不支援Sqrt方法,所以換用

for (BigInteger bi = 3; BigInteger.Pow(bi, 2) <= bigInteger; bi += 2)

 結果如下圖:

image

可以知道”30000000000000000000000000…………………………..1”不是質數,可以被13除盡。

 

2:C語言中有道經典的題目是求100!後面有幾個0.

如果你不知道BigInteger的話,應該怎麼做?

 100! 可以理解為image

 因為偶數比5要多,所以i值比j值多很多,所以求100!有多少個0,可以認為是求j的值

 

當然也可以用公式

 Sum = [100/5]+[100/(5^2)]+[100/(5^3)]=20+4+0=24;

 如果你既沒有思路,也沒有公式,腦子裡面只有一個念頭:1*2*3*4*5*..*100 的for迴圈,然後統計0的數量的話,在4.0 中也可以實現,雖然好像速度慢了點,不過也還是可以得到答案的:

 程式碼如下:

image

 

統計的程式碼如下:

執行結果如下:

int count = 0;
for (int i = strSum.Length - 1; i >= 0; i--)
{
    if (strSum[i] == '0')
    {
        count++;
    }
    else
    {
        break;
    }
}

 

 

image

 

還有很多使用大數的運算的地方,都等待著你的發揮!


相關文章