Math.Abs​​中的错误

时间:2013-04-09 12:17:47

标签: c#

我想将C#中一个非常大的负数转换为正值,但我知道当你点击Decimal.MaxValue时,Math.Abs​​会失败。我知道这个数字非常大,但是通过我的网络传输的数据可能会有这个或更大的数值。我想知道是否只是在C#中翻转数字的符号位。

这是我现在的代码:

int bucket = Math.Abs(sdmpobject.SnapshotHandle.GetHashCode()) % numPartitions;

这使用Math.Abs(),我只是想知道是否只有翻转符号位?

4 个答案:

答案 0 :(得分:3)

GetHashCode()始终返回32位整数(int)。这不可能超过Decimal.MaxValue 我假设在这里使用GetHashCode()是实际错误。

答案 1 :(得分:2)

GetHashCode()将返回int,而不是Decimal

Math.Abs(int)只有在传递的int等于int.MinValue时才会失败,因此您可以明确地测试该条件:

int myValue = sdmpobject.SnapshotHandle.GetHashCode();
int absValue = myValue == int.MinValue ? int.MaxValue : Math.Abs(myValue);
int bucket = absValue % numPartitions;

这假设您可以接受一个罕见的情况。由于您的结果位于一个名为“bucket”的变量中,您可能希望像这样对其进行更正:

int myValue = sdmpobject.SnapshotHandle.GetHashCode();
int bucket;
if (myValue == int.MinValue)
{
    bucket = ((int.MaxValue % numPartitions) + 1) % numPartitions;
}
else
{
    int bucket = Math.Abs(myValue) % numPartitions;
}

您不能仅为所有值“翻转符号”的原因是签名数据类型通常可以比正数包含多一个负数,因此它们不能代表它们可以容纳的最负数的绝对值。

答案 2 :(得分:0)

不是Abs失败,它是超出值的数值范围。

因此,您可能需要采用其他数字类型以避免出现问题 - 网络中的原始号码是什么类型/范围?

答案 3 :(得分:0)

在您的提问中,您提到了decimal,但您提供的示例是int

此外:

  

这使用Math.Abs​​(),我只是想知道是否只有翻转符号位?

是的,有一种方法,但你不想只是翻转符号位,因为这不会给你相应的值(即在-1上翻转符号位不会导致在1)