【问题标题】:Get Last 2 Decimal Places with No Rounding获取最后 2 个小数位且不四舍五入
【发布时间】:2012-03-29 19:05:51
【问题描述】:

在 C# 中,我试图在不进行四舍五入的情况下获取双精度数的最后两位小数。我已经尝试了从Math.FloorMath.Truncate 的所有方法,但没有任何效果。

我想要的结果示例:

1,424.2488298 -> 1,424.24
53.5821 -> 53.58
10,209.2991 -> 10,209.29

有什么想法吗?

【问题讨论】:

标签: c# rounding decimal


【解决方案1】:

嗯,数学上很简单:

var f = 1.1234;
f = Math.Truncate(f * 100) / 100;  // f == 1.12

将小数点向右移动两位,转换为 int 以截断,将其向左移动两位。框架中可能也有方法可以做到这一点,但我现在看不到。你可以概括一下:

double Truncate(double value, int places)
{
    // not sure if you care to handle negative numbers...       
    var f = Math.Pow( 10, places );
    return Math.Truncate( value * f ) / f;
}

【讨论】:

  • 没那么简单。双精度型的范围比整数型更大。
  • @joe:啊,好点,改用 Math.Truncate,不需要强制转换
  • @EdS。我使用您的第一种方法对值 136.2025 进行了尝试,并将其修剪为 136.2 并删除了 0。有没有办法将 0 保留在其中?
  • @mint:嗯,现在你说的是显示,而不是数字本身。 136.2136.20136.2000000 之间没有区别。如果您想打印一定数量的显示位置,请查看对String.Format 的调用中的字符串格式。
  • @mint:请务必注意 Eric Lippert 在他的帖子中所说的话。使用decimal 类型可能会更好,如果乘法结果大于double 的最大值,则乘法将失败。
【解决方案2】:

我的建议:首先停止使用double。如果您需要小数舍入,那么您应该使用decimal。你的申请是什么?

如果你有双倍,你可以这样做:

double r = whatever;
decimal d = (decimal)r;
decimal truncated = decimal.Truncate(d * 100m) / 100m;

请注意,如果双精度数的绝对值大于 792281625142643375935439504,则此技术将失败,因为乘以 100 将失败。如果您需要处理那么大的值,那么您将需要使用特殊技术。 (当然,当双精度值这么大时,你已经远远超出了它用小数点后两位表示值的能力。)

【讨论】:

    【解决方案3】:
     double d = Math.Truncate(d * 100) / 100;
    

    【讨论】:

      【解决方案4】:

      一个通用的解决方案:

          public static double SignificantTruncate(double num, int significantDigits)
          {
              double y = Math.Pow(10, significantDigits);
              return Math.Truncate(num * y) / y;
          }
      

      然后

          double x = 5.3456;
          x = SignificantTruncate(x,2);
      

      将产生所需的结果x=5.34

      【讨论】:

        【解决方案5】:
        Math.Round(NumberToRound - (double)0.005,2)
        

        Math.Round(53.5821 - (double)0.005,2) // 53.58
        Math.Round(53.5899 - (double)0.005,2) // 53.58
        Math.Round(53.5800 - (double)0.005,2) // 53.58
        

        【讨论】:

          【解决方案6】:

          Octane 我概括了你的答案,它不会受到超过最大值的影响.. 就像一个魅力:)

          int dec = 4; 
          return Math.Round(val - (decimal)(5 / Math.Pow(10,dec+1)), dec)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-03
            • 1970-01-01
            • 1970-01-01
            • 2015-11-24
            • 2012-03-11
            • 2014-02-10
            相关资源
            最近更新 更多