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