我正在进行一些自定义序列化操作,为了节省空间,如果可能的话,我希望将小数序列化为整数。由于我正在处理大量数据,因此性能是一个问题。我目前使用的方法是:
if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
return true;
}
这个能不能改进?
我正在进行一些自定义序列化操作,为了节省空间,如果可能的话,我希望将小数序列化为整数。由于我正在处理大量数据,因此性能是一个问题。我目前使用的方法是:
if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value))
{
return true;
}
这个能不能改进?
你的无效条件如下:
1)它是否大于最大值?
2)它是否小于最小值?
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进行解码以转换为/从十进制。
你有任何负数吗?我猜想是的,因为你有MinValue检查,否则你可以跳过它。你甚至可以使用无符号整型,这将允许您将更多的双精度值转换为整数。
编辑:此外,如果您有更多正数,则可以交换前两个条件。这样第一个条件最可能失败,从而减少总比较次数。
你不是可以做类似这样的事情吗:
if(Decimal.ToInt32(value) == value)
{
return true;
}
虽然我不是 .net 的专家,但我认为那应该就是所需的全部。此外,你的两个比较运算符应该是“或等于”,因为最小/最大值也是有效的。
编辑:正如评论中指出的那样,这会抛出异常。你可以尝试捕获异常并返回 false,但此时自己进行最小/最大值测试可能会更快。
不需要 "valueAsInt ="。我相信 (Decimal.ToInt32(value) == value)) 可以得到相同的结果,而且少了一个赋值。你是把 valueAsInt 用作某种输出参数吗?