【发布时间】:2011-04-06 17:42:39
【问题描述】:
我在数据存储中有一些列使用 12 位小数精度。
为了通过文本提要发送它,我想将它四舍五入到 4 个位置,并且该提要的消费者需要 x 精度。
我使用的是自定义构建的工作流引擎,在任何执行点都无法直接访问代码,但可以使用条件在任何字段上注入代码,例如:
if (obj.myValue.HasValue)
obj.myValue = System.Math.Round(obj.MyValue.Value, 4)
上面的例子可以进行四舍五入,但在某些 情况下不会删除尾随的 0。使用 obj.myValue.ToString() 自动生成的最终结果(等等,所有字段)
这似乎只发生在可为空的十进制字段上。
我不确定有什么不同,但在大约 10% 的行中,输出保留了尾随 0。实际值被四舍五入,但0s保留:
134.402100000000
我也尝试过这样做(只是为了确保并删除小数的初始精度)
if (obj.myValue.HasValue)
obj.myValue = decimal.Parse(obj.MyValue.Value.ToString("#.####"))
同样,一些行保留附加的尾随 0。
看起来该属性已初始化为 x 位小数,以及最终的 ToString。
考虑到我没有直接访问此代码的权限,但可以注入任何要在该属性上执行的 c#,还有其他我可以尝试的方法吗? (我还尝试将所有行硬编码为一个值,并且没有额外的 0 可以正常工作)
另外有趣的是我无法在我的测试中重现这种行为..
decimal d1 = 160236194.3900000000000001M;
Console.WriteLine(d1);
d1 = Math.Round(d1, 4);
Console.WriteLine(d1);
160236194.3900000000000001
160236194.3900
Press any key to continue . . .
编辑
感谢 e.James 尝试了另一种方法(测试截断是否会删除 0)
if (obj.myValue.HasValue)
obj.myValue = decimal.Truncate(obj.MyValue.Value)
并且.. 截断适用于所有行,但 0 仍然保留在之前的行上!不同的是,这一次它只有 0s.. 在截断之前是 .8900000000 等等。这太疯狂了!
【问题讨论】:
-
非二进制表示的浮点数应该是这里某处的主要常见问题解答条目