我猜测这是由于浮点数和精度的问题,但我想确认一下是否还有其他的遗漏。
我有一个浮点数(存储在info.Amount中),为1007.62,乘以100后转换为long类型。此时,我得到了一个值为100761。
这只是我们在应用Double时遇到的老问题“四舍五入误差”吗?我唯一能想出来的方法就是,在其底层实际上存储为1007.6199999999999(但为显示目的而四舍五入)。然后,在乘法之后,将其转换为long类型并忽略小数点后面的所有内容?
我猜测这是由于浮点数和精度的问题,但我想确认一下是否还有其他的遗漏。
我有一个浮点数(存储在info.Amount中),为1007.62,乘以100后转换为long类型。此时,我得到了一个值为100761。
这只是我们在应用Double时遇到的老问题“四舍五入误差”吗?我唯一能想出来的方法就是,在其底层实际上存储为1007.6199999999999(但为显示目的而四舍五入)。然后,在乘法之后,将其转换为long类型并忽略小数点后面的所有内容?
float z = 1007.62f;
z.Dump();
float x = z *100;
x.Dump();
long l = (long) (z*100);
l.Dump();
l = Convert.ToInt64(z*100);
l.Dump();
l = Convert.ToInt64(x);
l.Dump();
结果是:
1007,62
100762
100761
100762
100762
这里的 cast (long) (z*100)
使用了 CIL-instruction conv.i8
,它将转换为 Int64 并将 Int64 推入堆栈,而 Convert.ToInt64
使用 Math.Round(double)
来进行转换/强制类型转换为 Int64。
关于 conv.i8
的特殊说明是:
从浮点数向整数值的转换会朝着零方向截断数字。
double amount = 1007.62;
long result = (long) (amount*100);
结果绝对是100762,没有任何小数或四舍五入。实际上,1007.62是一个双精度数字,不应该存储为浮点数,否则可能会导致像你遇到的问题一样的进一步问题。