C#有一个好的,高性能的无符号BigInteger类型吗?

时间:2011-05-10 05:35:34

标签: c# biginteger unsigned

我熟悉System.Numerics.BigInteger类,但在我的应用程序中,我只处理正整数。负整数是一个错误的情况,如果有一个无符号等效的BigInteger类型它会很好,所以我可以删除所有这些检查。是否存在?

5 个答案:

答案 0 :(得分:2)

框架中没有任何内容,没有。我会尝试将检查集中在尽可能小的公共API中,然后在剩下的时间内将数据视为有效 - 就像对待null检查一样。当然,如果您执行任何创建负值的操作(例如从另一个中减去一个),您仍需要小心。

您可以通过创建扩展方法使代码稍微整洁,例如

public static void ThrowIfNegative(this BigInteger value, string name)
{
    if (value.Sign < 0)
    {
        throw new ArgumentOutOfRangeException(name);
    }
}

...并像这样使用它:

input.ThrowIfNegative("input");

您可以创建自己的UBigInteger结构,其中包含BigInteger,并使用BigInteger实现和检查在不同值之间执行操作,但我怀疑这将是一个如果您将其用于大量计算,那么可能会产生性能影响。

答案 1 :(得分:1)

如果您只使用BigInteger API的一个相当小的子集,那么编写自己的包装类很容易,如果费力的话。下面是一些示例代码,用于演示它不需要那么大的操作:

public struct UnsignedBigInteger
{
    private BigInteger value;
    private UnsignedBigInteger(BigInteger n) { value = n; }

    public UnsignedBigInteger(uint n) { value = new BigInteger(n); }
    // ... other constructors ...

    public static UnsignedBigInteger operator+(UnsignedBigInteger lhs, UnsignedBigInteger rhs)
    {
        return new UnsignedBigInteger(lhs.value + rhs.value);
    }
    public static UnsignedBigInteger operator-(UnsignedBigInteger lhs, UnsignedBigInteger rhs)
    {
        var result = lhs.value - rhs.value;
        if (result < BigInteger.Zero) throw new InvalidOperationException("value out of range");
        return new UnsignedBigInteger(result);
    }
    // ... other operators ...
}

答案 2 :(得分:1)

好吧,让我们来看一个简单的例子

        uint a=1;
        uint b=2;
        uint c=a-b;
        Console.WriteLine(c);

为您提供输出4294967295(= 2 ^ 32-1)。

但是如果你有一个具有类似行为的无符号BigInteger怎么办?

        UBigInteger a(1);
        UBigInteger b(2);
        UBigInteger c=a-b;
        Console.WriteLine(c.ToString());

应该是什么?当然,根据您所写的内容,您可以假设在这种情况下您可能会遇到某种异常,但这种行为与int不一致。更好地介绍检查&lt; 0,你需要它们,例如,像Jon Skeet建议的那样。

答案 3 :(得分:-1)

如果负值出现这样的问题,有可能以某种方式消除它们,以便坏数据(负值)甚至不能达到你的逻辑吗?这将消除所有检查。你能发一个你正在做的简短片段吗?

答案 4 :(得分:-3)

框架中没有任何支持将BigInteger声明为unsigned。但是,您可以创建一个静态方法来检查数字是否为负数。

public static void ValidateBigIntForUnsigned(BigInteger bigInteger)
{
   if(bigInteger.Sign < 0)
       throw new Exception("Only unsigned numbers are allowed!");
}