【问题标题】:Working with BigIntegers in C#在 C# 中使用 BigIntegers
【发布时间】:2010-12-05 19:00:18
【问题描述】:

我正在测试 BigIntegers。

当我取一个大的奇数除以 2 时,我得到一个整数作为 anwser,没有任何迹象表明它不能精确地除这个数。

所以第一个问题是我怎么知道两个数字完全除。

然后我用一个小数字测试了它,这个代码:

        string myNumberAsString = "25";
        System.Text.UTF8Encoding  encoding=new System.Text.UTF8Encoding();
        byte[] myNumberAsByteArray = encoding.GetBytes(myNumberAsString);
        BigInteger myNumber = new BigInteger(myNumberAsByteArray);
        Console.WriteLine(myNumber / 2);

给出的结果是 6809。有人知道为什么或者可以看到我的代码有什么问题吗?

我正在使用 BigInteger 的 .net 4.0 实现

【问题讨论】:

  • 我不认为编码为 UTF8 会给你一个代表数字 25 的字节数组?
  • 6809 十六进制是 0x1A99,正好是 0x3532 的一半。字符串中字符的 ASCII 码(UTF-8 对 ASCII 范围内的字符使用 ASCII 码)是 0x32 和 0x35,由于 little-endian 字节顺序,它们变为 0x3532。所以你的“大整数”并不奇怪,除法会给你正确的结果。

标签: c# .net-4.0 biginteger


【解决方案1】:

除了其他人指出的字符串到 BigInteger 的转换问题之外,将两个 BigInteger 相除总是会产生 BigInteger 结果(因为整数没有小数部分)。这个结果将是浮点结果的整数部分。

要确定划分是否准确,请使用DivRem() 方法:

var dividend = BigInteger.Parse("25");

BigInteger remainder;
var quotient = BigInteger.DivRem(dividend, 2, out remainder);
if (!remainder.IsZero) {
    throw new Exception("Division resulted in remainder of " + remainder + "!");
}

【讨论】:

    【解决方案2】:

    我不知道您正在使用BigInteger 的什么实现,但myNumberAsByteArray 不会包含代表数字25 的字节。您只是在这里将字符串转换为字节。您可以使用字符串myNumberAsString = "abc";,这会给您另一个结果。

    您可能想改用Parse 方法:

    BigInteger myNumber = BigInteger.Parse("25");
    

    【讨论】:

    • BigInteger 是 System.Numerics 的一部分,因为 .Net 4
    • @Cameron,我知道这一点,但 OP 应该指定它。还有其他可能的实现方式。
    【解决方案3】:

    如果您必须从数字的字符串表示形式进行转换,请使用BigInteger.TryParseBigInteger.Parse

    但是,无论您如何实例化您的 BigInteger,您都可以通过使用模数学来确定一个数是否可​​以被另一个数整除。例如,如果您想查看 someNumber 是否可被 2 整除,则只需验证 (someNumber % 2) == 0(即 sumNumber / 2 的余数为零)。这适用于任何整数分母。只需将 2 替换为您要测试的分母即可。但是,对于 BigInteger,您可能应该使用 DivRem 方法而不是 % 运算符。

    【讨论】:

    • 我收回我所说的关于 DivRem 的话。这不是真的必要,但肯定是可以接受的。模数运算符(%)很好。尽可能避免隐式数据类型转换。
    【解决方案4】:

    您构建 BigInteger 的方式过于复杂 - 该框架提供来自 byteInt16 等的隐式转换:

    BigInteger myNumber = 25;
    Console.WriteLine(myNumber / 2);
    

    要从字符串表示转换更大的数字,请使用BigInteger.Parse()

    BigInteger myNumber = BigInteger.Parse("252525252525252525252525252525");
    Console.WriteLine(myNumber / 2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-12
      • 2022-01-05
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      相关资源
      最近更新 更多