将double值乘以100.0会引入舍入误差?
这就是我正在做的事情,99.999%的时间工作:
((int)(customerBatch.Amount * 100.0)).ToString()
金额值是双倍的。 我试图将价值以便士的价格写入文本文件,以便传输到服务器进行处理。 金额绝不会超过2位精度。
如果您使用580.55作为金额,则此行代码返回58054作为字符串值。
此代码在64位Web服务器上运行。
有任何想法吗?
你应该使用十进制进行货币计算。
((int)(580.55m * 100.0m)).ToString().Dump();
您可以使用decimal
值进行准确计算。 Double是浮点数,在计算过程中不能保证精确。
我猜测580.55正在转换为58054.99999999999999999999999999 …,在这种情况下int将它向下舍入到58054.您可能想要编写自己的函数,将您的金额转换为具有某种舍入或阈值的int这不会发生。
尝试
((int)(Math.Round(customerBatch.Amount * 100.0))).ToString()
由于诸如此类的舍入错误,您实际上不应该使用double值来表示货币。
相反,您可以考虑使用积分值来表示货币金额,以便准确表示它们。 要表示小数,您可以使用类似的技巧将580.55
存储为值58055
。
不,乘法不会引入舍入误差,但并非所有值都可以通过浮点数表示。 x.55是其中之一)
十进制比双精度更精确。 尝试小数点。
http://msdn.microsoft.com/en-us/library/364x0z75%28VS.80%29.aspx
我的建议是将值存储为便士的整数,并dollars_part = pennies / 100
cents_part = pennies % 100
dollars_part = pennies / 100
和cents_part = pennies % 100
。 这将完全避免舍入错误。
编辑:当我写这篇文章时,我没有看到你无法改变数字格式。 最好的答案可能是使用其他人建议的圆形方法。
编辑2:正如其他人所指出的那样,最好使用某种定点十进制变量。 这比我原来的解决方案更好,因为它会将有关小数点位置的信息存储在它所属的值中而不是代码中。
- 在C#.NET中使用单个值初始化整数数组
- 如何在不使用所有子节点中的XNamespace的情况下为子节点创建具有默认命名空间的XElement
- 一个用于UserControl和Window的ViewModel或单独的ViewModel
- foreach with generic List,在使用值类型时检测第一次迭代
- 如何在C#中自动交换2个int?
- 使用C#在Little或Big Endian中写入/读取二进制数据的最佳方法?
- Control.invoke和父控件
- .NET中是否可以使用不可变数组?
- 在Travis CI上使用Mono 5.14.0.177,msbuild 15.0,nuget 4.7.1构建失败,但在VirtualBox中无法重现