需要一个数据类型来容纳 100 万个数据+ C# 中的数字

发布于 2024-11-04 01:27:52 字数 596 浏览 9 评论 0原文

我正在用 C# 计算 PI,到目前为止它很完美,除了我的数据类型限制了我。 如果我使用双精度,我会得到如下结果。

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

正如您可能注意到的,到第四次运行时,我的数字已达到最大值。十进制只能帮助一点点,但我需要很多。我的算法循环并添加。

我考虑过使用字符串,但我的问题是,如果我没有数据类型来保存这些数字,如何将它们放入字符串中?

我知道人们以前已经这样做过,我只是想知道如何...

感谢您的建议!

I am calculating PI in C#, and so far its perfect except my data types are limiting me.
If i use a double i get results like below.

k=0, delta= 3,14176587301587, pi=3,14176587301587

k=1, delta=-0,000173301147482709, pi=3,14159257186839

k=2, delta= 8,17736604635702E-08, pi=3,14159265364205

k=3, delta=-5,22954018637708E-11, pi=3,14159265358975

k=4, delta= 3,78997628626364E-14, pi=3,14159265358979

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

As you may notice, by my fourth run my digits are maxed. And decimal only helps for a little bit more, but i need A LOT. My algorithm loops and adds.

I thought about using a string, but my problem is, if i don't have a data type to hold those digits how do i get them into a string?

And i know people have done this before, i just wonder how...

Thanks for any advice!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静待花开 2024-11-11 01:27:52

您可以使用 CodeProjectSwensen.BigInt.dll 程序集>。如果需要.net 2.0版本,可以下载

You can use Swensen.BigInt.dll assembly from CodeProject. If you need a .net 2.0 version, you can download it here.

述情 2024-11-11 01:27:52

您可以使用 BigInteger 存储小数点后的所有内容。

You could use BigInteger to store everything after the decimal point.

栀梦 2024-11-11 01:27:52

使用这个代码,它就像一个魅力

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;
      }
    }
}

Use this code, it works like a charm

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;
      }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文