2011-05-01 74 views
3

我正在計算C#中的PI,到目前爲止,除了我的數據類型以外,它的完美限制了我。 如果我使用雙我得到如下結果。需要一種數據類型來保存C#中的一百萬位數字

K = 0δ= 3,14176587301587,PI = 3,14176587301587

k = 1時,三角= -0,000173301147482709,PI = 3,14159257186839

k = 2時,增量= 8 ,17736604635702E-08,PI = 3,14159265364205

K = 3,δ-= -5,22954018637708E-11,PI = 3,14159265358975

K = 4,δ-= 3,78997628626364E-14,PI = 3,14159265358979

k = 5,delta = -2,94045250629684E-17,pi = 3,14159265358979

正如你可能注意到的,在我的第四次運行中,我的數字是最大的。而小數只有一點點幫助,但我需要很多。我的算法循環並添加。

我想過使用一個字符串,但我的問題是,如果我沒有一個數據類型來容納這些數字我怎麼讓他們進入一個字符串?

而且我知道之前的人已經這樣做了,我只是不知道如何...

感謝您的諮詢!

+0

[任意精度的小數在C#(的可能重複http://stackoverflow.com/questions/4523741/arbitrary-precision-decimals-in -c) – kennytm 2011-05-01 06:39:38

+0

通過使用十進制你得到了:3.1415926535897932384626433832,沒有更多 – 2011-05-01 07:05:12

回答

2

您可以使用BigInteger來存儲小數點後的所有內容。

+0

這是它的概率需要.net 4.0 如果我必須使用它..我想我會,但我寧願一種方式是.net 2.0和能夠。 – 2011-05-01 06:42:07

+0

即使這樣BigInteger也存在問題,因爲它是不可變的,因此您需要分配許多大對象。 – CodesInChaos 2011-05-01 10:20:54

3

您可以使用Swensen.BigInt.dll彙編CodeProject。如果你需要.net 2.0版本,你可以下載它here

+0

您將CodePlex與CodeProject混淆;-) – 2011-05-01 10:18:41

+1

哦,對不起,我修正了它。 – oxilumin 2011-05-01 10:20:17

0

使用此代碼,它就像一個魅力

using System; 
using System.Text; 

class Solution 
{ 
    static void Main(string[] args) 
    { 
     BigNumber x = new BigNumber(100); 
     BigNumber y = new BigNumber(100); 
     x.ArcTan(16, 5); 
     y.ArcTan(4, 239); 
     x.Subtract(y); 
     stopWatch.Stop(); 
     Console.WriteLine(x.Print());  
     Console.ReadLine(); 
    } 
} 
public class BigNumber { 
    private UInt32[] number; 
    private int size; 
    private int maxDigits; 

    public BigNumber(int maxDigits) { 
     this.maxDigits = maxDigits; 
     this.size = (int) Math.Ceiling((float)maxDigits * 0.104) + 2; 
     number = new UInt32[size]; 
    } 
    public BigNumber(int maxDigits, UInt32 intPart) 
     : this(maxDigits) { 
     number[0] = intPart; 
     for (int i = 1; i < size; i++) { 
     number[i] = 0; 
     } 
    } 
    private void VerifySameSize(BigNumber value) { 
     if (Object.ReferenceEquals(this, value)) 
     throw new Exception("BigNumbers cannot operate on themselves"); 
     if (value.size != this.size) 
     throw new Exception("BigNumbers must have the same size"); 
    } 
    public void Add(BigNumber value) { 
     VerifySameSize(value); 

     int index = size - 1; 
     while (index >= 0 && value.number[index] == 0) 
     index--; 

     UInt32 carry = 0; 
     while (index >= 0) { 
     UInt64 result = (UInt64)number[index] + 
         value.number[index] + carry; 
     number[index] = (UInt32)result; 
     if (result >= 0x100000000U) 
      carry = 1; 
     else 
      carry = 0; 
     index--; 
     } 
    } 
    public void Subtract(BigNumber value) { 
     VerifySameSize(value); 

     int index = size - 1; 
     while (index >= 0 && value.number[index] == 0) 
     index--; 

     UInt32 borrow = 0; 
     while (index >= 0) { 
     UInt64 result = 0x100000000U + (UInt64)number[index] - value.number[index] - borrow; 
     number[index] = (UInt32)result; 
     if (result >= 0x100000000U) 
      borrow = 0; 
     else 
      borrow = 1; 
     index--; 
     } 
    } 
    public void Multiply(UInt32 value) { 
     int index = size - 1; 
     while (index >= 0 && number[index] == 0) 
     index--; 
    enter code here 
     UInt32 carry = 0; 
     while (index >= 0) { 
     UInt64 result = (UInt64)number[index] * value + carry; 
     number[index] = (UInt32)result; 
     carry = (UInt32)(result >> 32); 
     index--; 
     } 
    } 
    public void Divide(UInt32 value) { 
     int index = 0; 
     while (index < size && number[index] == 0) 
     index++; 

     UInt32 carry = 0; 
     while (index < size) { 
     UInt64 result = number[index] + ((UInt64)carry << 32); 
     number[index] = (UInt32) (result/(UInt64)value); 
     carry = (UInt32)(result % (UInt64)value); 
     index++; 
     } 
    } 
    public void Assign(BigNumber value) { 
     VerifySameSize(value); 
     for (int i = 0; i < size; i++) { 
     number[i] = value.number[i]; 
     } 
    } 

    public string Print() { 
     BigNumber temp = new BigNumber(maxDigits); 
     temp.Assign(this); 

     StringBuilder sb = new StringBuilder(); 
     sb.Append(temp.number[0]); 
     sb.Append(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator); 

     int digitCount = 0; 
     while (digitCount < maxDigits) { 
     temp.number[0] = 0; 
     temp.Multiply(100000); 
     sb.AppendFormat("{0:D5}", temp.number[0]); 
     digitCount += 5; 
     } 

     return sb.ToString(); 
    } 
    public bool IsZero() { 
     foreach (UInt32 item in number) { 
     if (item != 0) 
      return false; 
     } 
     return true; 
    } 

    public void ArcTan(UInt32 multiplicand, UInt32 reciprocal) { 
     BigNumber X = new BigNumber(maxDigits, multiplicand); 
     X.Divide(reciprocal); 
     reciprocal *= reciprocal; 

     this.Assign(X); 

     BigNumber term = new BigNumber(maxDigits); 
     UInt32 divisor = 1; 
     bool subtractTerm = true; 
     while (true) { 
     X.Divide(reciprocal); 
     term.Assign(X); 
     divisor += 2; 
     term.Divide(divisor); 
     if (term.IsZero()) 
      break; 

     if (subtractTerm) 
      this.Subtract(term); 
     else 
      this.Add(term); 
     subtractTerm = !subtractTerm; 
     } 
    } 
} 
相關問題