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

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

可以改进吗?

有帮助吗?

解决方案

您有负值吗?我猜是的,因为您有Minvalue检查,否则可以跳过。您甚至可以使用未签名的INT,这将使您可以将更多的双重值转换为INT。

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

其他提示

您的无效标准是:

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;
}

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

    return (value == (Int32)value);

还要记住,如果是 if 声明只是返回布尔值,您只需返回比较即可。仅此一项就可以使其更快(除非编译器已经对此进行了优化)。如果您必须使用if语句,则可以类似地执行此操作:

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

编辑: 我意识到这实际上不起作用。我以为INT32演员将仅在小数点的前32位中复制,而留下了剩下的任何位(也不是例外),但是可惜,它没有用这种方式(更不用说这是错误的所有负值)。

这取决于您有多少个小数或真正关心的地方。如果您可以说我只关心多达3个小数位置,那么您可以在INT32中存储的最大数字是int.maxvalue /1000。如果您仅使用正数,则可以使用UINT获得更高的数字。无论如何,这样做的方法是始终保留小数的空间,并使用 * 1000对其进行编码和 / 1000以将其解码为 /从十进制。

无需“ valueasint =”。我相信(DECIMAL.TOINT32(value)== value))为您提供相同的结果,而分配较少。您是否使用ValueAsint作为某种输出参数?

您是否可以做类似的事情:

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

不是.NET的专家,但我认为这应该是全部所需的。同样,您的两个比较运算符应为“或相等”,因为最小/最大值也有效。

编辑:正如评论中指出的那样,这将引发例外。您可以尝试捕获异常并返回错误,但是在那时,进行最小/最大测试的速度可能会更快。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top