4

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

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

这可以改进吗?

4

6 回答 6

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;
}
于 2010-04-29T15:32:32.867 回答
1

这个怎么样。我认为它应该需要更少的操作(至少更少的比较次数):

    return (value == (Int32)value);

还要记住,如果一个if语句只返回一个布尔值,你可以只返回比较。仅此一项可能会使其更快(除非编译器已经为此进行了优化)。如果你必须使用 if 语句,你可以类似地这样做:

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

编辑:我意识到这实际上不起作用。我在想 Int32 转换只会复制十进制的前 32 位,留下任何剩余的位(并且不会抛出异常),但是唉,它不是那样工作的(更不用说它对所有负值)。

于 2010-04-29T15:33:49.790 回答
1

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

于 2010-04-29T15:39:03.603 回答
1

你有负面的价值观吗?我猜是的,因为你有 MinValue 检查,否则你可以跳过它。您甚至可以使用 unsigned int 来将更多的双精度值转换为整数。

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

于 2010-04-29T18:18:25.247 回答
0

难道你不能做类似的事情:

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

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

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

于 2010-04-29T15:33:00.803 回答
0

不需要“valueAsInt =”。我相信 (Decimal.ToInt32(value) == value)) 只需少分配一项即可获得相同的结果。您是否使用 valueAsInt 作为某种输出参数?

于 2010-04-29T15:34:18.687 回答