C#是否有一种性能良好的无符号BigInteger类型?

C#是否有一种性能良好的无符号BigInteger类型?,c#,biginteger,unsigned,C#,Biginteger,Unsigned,我熟悉System.Numerics.BigInteger类,但在我的应用程序中,我只处理正整数。负整数是一种错误情况,如果有BigInteger类型的无符号等价物,那么我就可以删除所有这些检查。是否存在?框架中不支持将biginger声明为无符号。但是,您可以创建一个静态方法来检查数字是否为负数 public static void ValidateBigIntForUnsigned(BigInteger bigInteger) { if(bigInteger.Sign < 0)

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

框架中不支持将
biginger
声明为
无符号
。但是,您可以创建一个静态方法来检查数字是否为负数

public static void ValidateBigIntForUnsigned(BigInteger bigInteger)
{
   if(bigInteger.Sign < 0)
       throw new Exception("Only unsigned numbers are allowed!");
}
public静态void ValidateBigIntForUnsigned(biginger-biginger)
{
if(bigInteger.Sign<0)
抛出新异常(“只允许未签名的数字!”);
}

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

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

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

您可以创建自己的
UBigInteger
结构,其中包含一个
biginger
,并通过使用
biginger
实现和检查在不同的值之间执行操作,但我怀疑这将是相当多的工作,但好处相对较小,若您在大量计算中使用它,可能会影响性能。

若您只使用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 ...
}
public结构unsignedbiginger
{
私有大整型值;
私有无符号BigInteger(BigInteger n){value=n;}
public unsignedbiginger(uint n){value=new biginger(n);}
//…其他构造函数。。。
公共静态无符号BigInteger运算符+(无符号BigInteger lhs、无符号BigInteger rhs)
{
返回新的unsignedbiginger(lhs.value+rhs.value);
}
公共静态unsignedbiginger运算符-(unsignedbiginger lhs,unsignedbiginger rhs)
{
var结果=lhs.value-rhs.value;
如果(结果
好吧,让我们看一个简单的例子

        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
不一致。最好在需要的地方引入<0的检查,例如,就像Jon Skeet建议的那样

如果负值出现这样的问题,是否有可能以某种方式消除它们,使坏数据(负值)甚至无法到达您的逻辑?这将消除所有检查。你能发一个你正在做的事情的小片段吗?

我想你在想T-SQL的
BigInt
?如果是这样,那么
System.Numerics.BigInteger
不是。。。如果有这样的类型,它更像varint(max)。@LasseSpeholt看一看。
System.Numerics.BigInteger
是一个任意长度的整数,而不是您认为的64位。它们可能有相同的名称,但它们并不等同。它在SQL中被称为
BigInt
。好吧,我错了,我以为他说的是TSql BigInt。@Splendor:我不认为这是真正的问题……谢谢Jon。我已经删除了我的评论。我不明白为什么你会说(a)负数是一个错误案例,而(b)你想创建一个无符号类型,那会做什么?如果尝试分配负值,是否引发异常?
        UBigInteger a(1);
        UBigInteger b(2);
        UBigInteger c=a-b;
        Console.WriteLine(c.ToString());