两个大数字之间的差异C#

对于小数字,已经有解决这个问题的方法:

  • 这里: 2个数字之间的差异
  • 这里: C#函数找到两个数字的增量
  • 这里: 如何在C#中找到2个值之间的差异?

我将总结所有人的答案:

Math.Abs(a - b) 

问题是当数字很大时,这会给出错误的答案(通过溢出)。 更糟糕的是,如果(a - b) = Int32.MinValueMath.Abs因exception而崩溃(因为Int32.MaxValue = Int32.MinValue - 1 ):

发生了System.OverflowException
的HResult = 0x80131516
消息= 否定二进制补码数的最小值 无效
来源= mscorlib程序
StackTrace:在System.Math.Abs​​(Int32值)的System.Math.Abs​​Helper(Int32值)处

它的特殊性质导致难以重现的错误。

也许我错过了一些众所周知的库函数,但有没有办法安全地确定差异?

正如其他人所建议的那样,使用System.Numerics中定义的BigInteger(你必须在Visual Studio中包含命名空间)然后你可以这样做:

 BigInteger a = new BigInteger(); BigInteger b = new BigInteger(); // Assign values to a and b somewhere in here... // Then just use included BigInteger.Abs method BigInteger result = BigInteger.Abs(a - b); 

Jeremy Thompson的答案仍然有效,但请注意BigInteger命名空间包含绝对值方法,因此不需要特殊逻辑。 此外,Math.Abs​​需要一个小数,所以如果你尝试传入一个BigInteger,它会让你感到悲伤。

请记住,使用BigIntegers时需要注意。 如果你有一个非常大的数字,C#将尝试为它分配内存,你可能会遇到内存不足的exception。 另一方面,BigIntegers很棒,因为分配给它们的内存量随着数量的增加而动态变化。

有关详细信息,请查看microsoft参考: https : //msdn.microsoft.com/en-us/library/system.numerics.biginteger(v = vs.110).aspx

BigInteger是在.Net 4.0中引入的。

在较低版本的.Net Framework中有一些开源实现,但是你应该明智地选择标准。

如果Math.Abs仍然让你感到悲伤,你可以自己实现这个function; 如果数字是负数(a – b <0),只需修剪负数符号使其无符号。

另外,你尝试过使用双打吗? 它们拥有更大的价值。

问题是,你想如何保持两个大数字之间的差异? 例如,如果计算两个有符号长整数(64位)整数之间的差异,并且差异不适合有符号长整数,那么您打算如何存储它?

 long a = +(1 << 62) + 1000; long b = -(1 << 62); long dif = a - b; // Overflow, bit truncation 

ab之间的差异比64位宽,所以当它存储到一个长整数时,它的高位被截断,你得到一个奇怪的值。

换句话说, 您不能将给定宽度的有符号整数值之间的所有可能差异存储到相同宽度的有符号整数中。 (您只能存储所有可能值的一半;另一半需要额外的位。)

您可以选择使用更宽的类型来保持差异(如果您已经使用了最宽的long整数类型,这对您没有帮助),或者使用不同的算术类型。 如果您需要至少64个有符号的精度位,则可能需要使用BigInteger

这是您可能感兴趣的替代方案,但它非常符合特定int大小的范围。 此示例使用Int32,并使用按位运算符来完成差异,然后使用绝对值。 这个实现可以容忍你的场景,其中a-b等于min int值,它自然地返回min int值(你可以做的其他事情不多,而不会将事物转换为更大的数据类型)。 我不认为这和使用BigInteger一样好,但如果没有别的话,玩它很有趣:

  static int diff(int a, int b) { int xorResult = (a ^ b); int diff = (a & xorResult) - (b & xorResult); return (diff + (diff >> 31)) ^ (diff >> 31); } 

以下是我运行以下行为的一些案例:

  Console.WriteLine(diff(13, 14)); // 1 Console.WriteLine(diff(11, 9)); // 2 Console.WriteLine(diff(5002000, 2346728)); // 2655272 Console.WriteLine(diff(int.MinValue, 0)); // Should be 2147483648, but int data type can't go that large. Actual result will be -2147483648.