浮点数转换为长整型时出错

3

我猜测这是由于浮点数和精度的问题,但我想确认一下是否还有其他的遗漏。

我有一个浮点数(存储在info.Amount中),为1007.62,乘以100后转换为long类型。此时,我得到了一个值为100761。

enter image description here

这只是我们在应用Double时遇到的老问题“四舍五入误差”吗?我唯一能想出来的方法就是,在其底层实际上存储为1007.6199999999999(但为显示目的而四舍五入)。然后,在乘法之后,将其转换为long类型并忽略小数点后面的所有内容?


4
似乎之前已经讨论/回答过这个问题,请查看此处:https://dev59.com/SGox5IYBdhLWcg3w44Pb - 03Usr
@03Usr:谢谢 - 当我搜索/类似的问题时,没有找到任何东西。 - Ian
2个回答

5
你可以使用Convert.ToInt64代替。这将产生正确的值。
LinqPad-测试代码:
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 的特殊说明是:

从浮点数向整数值的转换会朝着零方向截断数字。


确实 - 这实际上是我选择的修复方式,正如您在我的截图中所看到的,我检查了几种不同的方法。 - Ian
@Ian,啊,好的,我没有注意到你图片中的那个。 - Jehof

1
实际上,我认为这是由你可能声明的变量引起的。
参考以下示例:
       double amount = 1007.62;
       long result = (long) (amount*100);

结果绝对是100762,没有任何小数或四舍五入。实际上,1007.62是一个双精度数字,不应该存储为浮点数,否则可能会导致像你遇到的问题一样的进一步问题。


可能是 - 这个值实际上是通过除法计算得出的。我没有特别声明它。 - Ian
你是否将你的属性(info.Amount)声明为float或double类型? - Ali Dehghan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接