为什么我会得到带有C#的Nuget BigInteger 1.0.7的System.ArithmeticException?

问题描述 投票:1回答:1

所以,我一直在学习C#,并测试了一些简单的算法。我做了一个简单的类,它公开了递归的斐波那契数函数。我使用记忆(动态编程)存储先前找到的数字。这是代码:

    using Godot;
    using System.Collections.Generic;

    public class Exercise1 : Node {
      private BigInteger teste = new BigInteger(1);
      private Dictionary<BigInteger,BigInteger> memory = new Dictionary<BigInteger,BigInteger>();
      public override void _Ready() {
        RunBigIntegerCraziness();
      }

    private void RunBigIntegerCraziness() {
      for (int i = 0; i < 31227; i++) {
        GD.Print($"fib number {i} is {fib(new BigInteger(i))}");
      }
    }

    private BigInteger fib(BigInteger n) {
      if (memory.ContainsKey(n)) {
        return memory[n];
      }

      if (n <= 2) {
        memory[n] = 1;
        return 1;
      }

      memory[n - 2] = fib(n - 2);
      memory[n - 1] = fib(n - 1);

      return memory[n - 2] + memory[n - 1];
    }
    }

忽略“ Godot”部分。只是我在游戏项目中进行了测试。一切都可以编译,但是我最多只能计算斐波那契数。 3226.如果我使用等于3227及更高的数字,则会出现此异常:

[...]FIB号3225是43217018697618272220345809139733426666656338842625944764401661804465121290773093888861438958973337206110398501101783011185091567135587979099219045977958276652741787987152919489957724618258731270111934419344108965974546742136386635343927537356176338553654798753734888560554135669621772542530920892471422002609630627040146600381068673360870794221630560104764217344676242315795514744073614579107596818134891238017641931792490286597416223216551326908997909707498658766245465906764466010328772845314077258564566442129155001040721886128505146365749238671331993692655687520038382893117763783477305776640877748401894737521738794911907045829607125767696264441933278046913082328818850FIB编号3226是69926605145186078778460989556214883682824163521963475389625827936774132010815037784261200216187927277027753726906285824183824754568491676416709800266452379691484582909141867315765704538889919267496081895355700988068705924800720430980434359659981529442293650167261872365958477365094269319478110803029308487644284790516508517647989046631899202985143468253781566270183590285229230335042129126551683888682955813507183937267823895233985645240278207971782178625906849647650415867576295127507836850507509010403410481726883571748090361307264480634218098397060429202475118649538779225621232854604363989464362465170636407301900981359138471646464444082736135056091569488488491377766743

未处理的例外:System.ArithmeticException:算术运算中的上溢或下溢。在BigInteger.op_Addition(BigInteger bi1,BigInteger bi2)中:[0x000fa]在:0中在/Users/rafael/gamedev/godot/mytests/CSharpStudy/study_classes/Exercise1.cs:31中的Exercise1.fib(BigInteger n)[0x000a8]中在/Users/rafael/gamedev/godot/mytests/CSharpStudy/study_classes/Exercise1.cs:15中的Exercise1.RunBigIntegerCraziness()[0x00006]中在/Users/rafael/gamedev/godot/mytests/CSharpStudy/study_classes/Exercise1.cs:10中的Exercise1._Ready()[0x00001]终端进程以退出代码终止:1

不是“ BigInteger”应该处理很高的数字吗?

c# biginteger arithmeticexception
1个回答
4
投票

在该BigInteger的来源中,有:

// maximum length of the BigInteger in uint (4 bytes)
// change this to suit the required level of precision.
private const int maxLength = 70;

长度以limbs计,在此实现中每个分支为32位。此外,最高肢的最高位被视为标志位。因此,在不更改源的情况下,这种BigInteger可以存储的最大数量(此限制not适用于System.Numerics中的BigInteger)为2 70 * 32-1-1,或换句话说,有2239个“正常”位可用。

[这允许一些相当大的整数,但还不够大:according to Wolfram Alpha fib(3227)仅需要2239位,因此不适合。

© www.soinside.com 2019 - 2024. All rights reserved.