确定小数是否可以存储为int32

时间:2010-04-29 15:26:39

标签: c# .net decimal int32

我正在做一些自定义序列化,为了节省一些空间,我希望将小数序列化为int,如果可能的话,值为明智。性能是一个问题,因为我正在处理大量数据。我使用的当前方法是:

if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
    return true;
}

可以改进吗?

6 个答案:

答案 0 :(得分:1)

您的无效标准是:

1)它是否大于MaxValue?

2)它是否小于MinValue?

3)它是否包含小数部分?

听起来你已经覆盖了它们。我的实施将是:

public bool IsConvertibleToInt(decimal value)
{
    if(value > int.MaxValue)
       return false;

    if(value < int.MinValue)
       return false;

    if(Math.Floor(value) < value && Math.Ceiling(value) > value)
       return false;

    return true;
}

答案 1 :(得分:1)

这个怎么样?我认为它应该花费更少的操作(至少少数比较):

    return (value == (Int32)value);

还要记住,如果if语句只返回一个布尔值,则可以返回比较。仅这一点可能会使它更快(除非编译器已经为此优化)。如果必须使用if语句,则可以类似地执行此操作:

    if (value == (Int32)value)
    {
        //Do stuff...
    return true;
    }
    else
    {
        //Do stuff...
        return false;
    }

编辑:我意识到这实际上并不奏效。我在想Int32演员只会复制小数的前32位,留下任何剩余的位(而不是抛出异常),但唉,它没有那样工作(更不用说它会错了)所有负值)。

答案 2 :(得分:1)

这取决于您拥有或真正关心的小数位数。如果你可以说我只关心最多3个小数位,那么你可以在int32中存储的最大数字是int.MaxValue / 1000.如果你只使用正数,那么你可以使用uint获得更高的数字。在任何情况下,这样做的方法是始终为小数保留空间并使用* 1000对它们进行编码,使用/ 1000将它们解码为/从十进制。

答案 3 :(得分:1)

你有任何负面价值观吗?我猜是的,因为你有MinValue检查,否则你可以跳过它。您甚至可以使用unsigned int,它允许您将更多的double值转换为int。

编辑另外,如果您有更多正数,则可以交换前两个条件。这样,第一个最有可能失败,减少了比较的总数。

答案 4 :(得分:0)

你不能只做以下事情:

if(Decimal.ToInt32(value) == value)
{
     return true;
}

不是.net的专家,但我认为这应该是它所需要的全部。此外,您的两个比较运算符应该是'或相等',因为最小/最大值也是有效的。

编辑:正如评论中指出的那样,这将引发异常。您可以尝试捕获异常并返回false,但此时自己进行最小/最大测试可能要快得多。

答案 5 :(得分:0)

不需要“valueAsInt =”。我相信(Decimal.ToInt32(value)== value))通过少一个任务获得相同的结果。您是否将valueAsInt用作某种输出参数?