【问题标题】:Unpredictable decimal summation C#不可预测的十进制求和 C#
【发布时间】:2015-01-08 14:30:00
【问题描述】:

我在 C#.NET 中遇到不可预测的小数行为。这是代码sn-p

decimal num1 = 2474M;
decimal num2 = 4947M;
decimal num3 = 4947M;
decimal sum = num1 + num2 + num3;

decimal perDouble1 = num1 / sum ;
decimal perDouble2 = num2 / sum ;
decimal perDouble3 = num3 / sum ;
decimal sumDouble = perDouble1 + perDouble2 + perDouble3;

输出:1.0000000000000000000000000001M

如果我将数字更改为

decimal num1 = 2474M;
decimal num2 = 4946M;
decimal num3 = 4947M;

输出为:1.0000000000000000000000000000M

我怎样才能避免这种情况?

【问题讨论】:

  • 你的问题到底是什么?
  • 来自MSDN的注释:The Decimal type does not eliminate the need for rounding. Rather, it minimizes errors due to rounding.
  • 至于如何避免,四舍五入。您可能不需要小数点后 28 位的精度,因此将其四舍五入到合理的位置。
  • 使用某种由两个BigIntegers 组成的 Rational 或 Fraction 类型。

标签: c# .net decimal


【解决方案1】:

一切都很好!

这不是不可预测的,类型 decimal 是一个近似值 (IEEE 754: 128bit)

解决此问题的一种方法是使用 BigNum 类。问题在于,.net 没有 1。它确实有 BigInteger (System.Numerics),但没有 BigDecimal。如果你想要 1,那么通常你会使用GNU GMP,但我认为不存在 C# 版本。

但是,只需 0 次努力,您就可以找到 GMP c# wrapper in beta

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    相关资源
    最近更新 更多