我正在做一些自定义序列化,为了节省一些空间,我希望将小数序列化为int,如果可能的话,值为明智。性能是一个问题,因为我正在处理大量数据。我使用的当前方法是:
if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
return true;
}
可以改进吗?
答案 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用作某种输出参数?