【问题标题】:How to safely convert from a double to a decimal in c#如何在 C# 中安全地从双精度转换为小数
【发布时间】:2011-02-18 17:46:39
【问题描述】:

我们使用小数数据类型将财务数据存储在 SQL Server 数据库中,并且我们需要 6-8 位的小数精度。当我们通过数据访问层将该值返回到 C# 服务器时,它会以十进制数据类型返回。

由于一些我无法控制的设计限制,这需要转换。转换为字符串不是问题。正如 MS 文档所说,转换为双精度数“[从十进制转换为双精度] 会产生舍入错误,因为双精度浮点数的有效数字少于小数。”

作为双精度数(或字符串),我们可以在任何计算完成后四舍五入到小数点后两位,那么进行小数转换以确保在四舍五入之前不会丢失任何精度的“正确”方法是什么?

【问题讨论】:

  • 根据 MSDN,decimal 的精度为 28-29 位,double 的精度为 15-16。但是,如果您只存储 6-8 位数字,那么我认为四舍五入不会影响您。这可以很容易地通过单元测试来查看。

标签: c#


【解决方案1】:

转换不会在前 8 位产生错误。 double 的精度为 15-16 位 - 比 decimal 的 28-29 位要少,但听上去足以满足您的目的。

您绝对应该制定某种计划以避免将来使用 double,但是 - 它是不适合财务计算的数据类型。

【讨论】:

  • 比我的评论快 15 秒! (+1):)
  • “这是一种不适合财务计算的数据类型。” 您能在闲暇时详细说明一下吗?这是我一直“知道”但不一定理解的事情之一。干杯! :)
  • @djacobson:财务计算通常以小数表示 - 人们期望(例如)0.01 和 0.01 相加的结果是恰好 0.02。这是double 中的技巧,其中 0.01 和 0.02 都不能准确表示。当然,如果你(比如说)除以 3,你仍然会丢失一些信息......但这对每个人来说都更容易理解(并且可能决定周围的政策),因为我们都习惯了十进制算术。一般来说,身高和体重等自然不精确的量适合加倍;精确的人造数量适合小数。
  • msdn.microsoft.com/en-us/library/aa326763(v=vs.71).aspx 有一个很棒的双十进制 .Net 代码示例,可以帮助您避免极端情况。
【解决方案2】:

如果您舍入到 2dp,IMO 的“正确”方式将存储一个整数,即倍数 - 即对于 12.34,您存储整数 1234。不再有双舍入的问题。

如果您必须使用 double,这仍然有效;保证所有整数都以 double 格式精确存储 - 所以仍然使用相同的技巧。

【讨论】:

  • 不会将 double 作为 int 存储考虑过早优化吗? 1.您将记住在视图、更新和保存中进行转换。 2.如果业务需求发生变化,那你就麻烦大了?如果财务部门以后想要小数点后 4 位怎么办?
  • 另外,您正在将最大/最小数字减少 2 位以使用它。因此,您现在只有 +/- 2000 万,而不是 +/- 20 亿。是的,你可以使用 Int64,但现在有什么意义呢?
  • @Holystream:我认为“整数”不是指Int32;我认为他的意思是“整数”。许多较旧的系统不支持Int64Decimal,但支持Double,它可以在不损失精度的情况下容纳高达4,503,599,627,370,496 的所有整数(或者,按100 倍缩放,所有便士金额都增加了至 45,035,996,273,704.96 美元)
猜你喜欢
  • 2020-11-22
  • 2017-10-11
  • 2012-12-02
  • 1970-01-01
  • 2012-12-04
  • 2011-04-10
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多