我在数据存储中有一些使用12位小数精度的列。
我想将其四舍五入到4个位置,以便通过文本Feed发送它,并且该Feed的使用者需要x精度。
我正在使用自定义构建的工作流引擎,并且无法在任何执行点直接访问代码,但可以使用条件在任何字段上注入代码,例如:
if (obj.myValue.HasValue)
obj.myValue = System.Math.Round(obj.MyValue.Value, 4)
以上示例适用于舍入,但在 SOME 情况下不会删除尾随0。使用obj.myValue.ToString()自动生成最终结果(依此类推,适用于所有字段)
这似乎只发生在可以为空的十进制字段上。
我不确定有什么不同,但在大约10%的行中,输出保留尾随0。实际值为四舍五入,但保持0:
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等。这很狂野!
答案 0 :(得分:3)
某些十进制数字无法以二进制格式完美表示。您的obj.myValue
属性是十进制数。对于某些小数,它根本无法存储除(例如)1234.4021000000000001之外的任何内容,它与有限位数的数据尽可能接近。
我认为Domenic对他的回答有正确的想法。让十进制数字在存储中保持不整齐,只显示*它们四舍五入。
如果绝对必须将数字四舍五入存储,则必须使用整数格式,然后在显示之前除以1000。 1234.4021将存储为12344021。
*注意:“显示”是指“输出到文字”,不一定是“向用户显示”
答案 1 :(得分:2)
为什么不让显示逻辑处理,呃,显示逻辑?也就是说,只有当您将decimal
显示为string
时,如果您关心显示的结尾0
的数量,在这种情况下您应该使用theDecimal.ToString("#.####")
。