【问题标题】:Truncate Decimal number not Round Off [duplicate]截断十进制数不四舍五入[重复]
【发布时间】:2010-09-24 16:53:09
【问题描述】:

可能重复:
c# - How do I round a decimal value to 2 decimal places (for output on a page)

我想像下面这样截断小数

  • 2.22939393 -> 2.229
  • 2.22977777 -> 2.229

【问题讨论】:

  • 我相信汇编指令 .trn 也会为您做到这一点。
  • 重复的问题没有说明没有截断的四舍五入。虽然相似,但这个问题的关键方面(不要四舍五入)没有被“重复”正确回答。投票重新开放。
  • 这不是重复的问题。我无法在此处发布我的解决方案,因为问题已关闭,因此我将其发布在类似的线程中:stackoverflow.com/questions/3143657/…

标签: .net floating-point truncate


【解决方案1】:

这类似于上面的 TcKs 建议,但使用 math.truncate 而不是 int 转换

VB:但你会明白的

Private Function TruncateToDecimalPlace(byval ToTruncate as decimal, byval DecimalPlaces as integer) as double 
dim power as decimal = Math.Pow(10, decimalplaces)
return math.truncate(totruncate * power) / power
end function

【讨论】:

    【解决方案2】:

    试试这个

    double d = 2.22912312515;
    int demention = 3;
    double truncate = Math.Truncate(d) + Math.Truncate((d - Math.Truncate(d)) * Math.Pow(10.0, demention)) / Math.Pow(10.0, demention);
    

    【讨论】:

      【解决方案3】:

      这是一种不受整数溢出影响的扩展方法(就像上面的一些答案一样)。它还缓存了一些 10 的幂以提高效率。

      static double[] pow10 = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10 };
      public static double Truncate(this double x, int precision)
      {
          if (precision < 0)
              throw new ArgumentException();
          if (precision == 0)
              return Math.Truncate(x);
          double m = precision >= pow10.Length ? Math.Pow(10, precision) : pow10[precision];
          return Math.Truncate(x * m) / m;
      }
      

      【讨论】:

        【解决方案4】:

        截断任意小数位数的函数:

        public decimal Truncate(decimal number, int digits)
        {
          decimal stepper = (decimal)(Math.Pow(10.0, (double)digits));
          int temp = (int)(stepper * number);
          return (decimal)temp / stepper;
        }
        

        【讨论】:

        • 这在System.OverflowException: Value was either too large or too small for an Int32的大量数字上失败
        【解决方案5】:

        忘记一切,看看这个

        double num = 2.22939393;
        num  = Convert.ToDouble(num.ToString("#0.000"));
        

        【讨论】:

        • 这是错误的。原始帖子正在寻找截断。这将圆。 2.2296 将导致 2.23。
        【解决方案6】:

        也许另一个快速的解决方案是:

        >>> float("%.1f" % 1.00001)
        1.0
        >>> float("%.3f" % 1.23001)
        1.23
        >>> float("%.5f" % 1.23001)
        1.23001
        

        【讨论】:

          【解决方案7】:

          试试这个:

          decimal original = GetSomeDecimal(); // 22222.22939393
          int number1 = (int)original; // contains only integer value of origina number
          decimal temporary = original - number1; // contains only decimal value of original number
          int decimalPlaces = GetDecimalPlaces(); // 3
          temporary *= (Math.Pow(10, decimalPlaces)); // moves some decimal places to integer
          temporary = (int)temporary; // removes all decimal places
          temporary /= (Math.Pow(10, decimalPlaces)); // moves integer back to decimal places
          decimal result = original + temporary; // add integer and decimal places together
          

          它可以写得更短,但这更具描述性。

          编辑:捷径:

          decimal original = GetSomeDecimal(); // 22222.22939393
          int decimalPlaces = GetDecimalPlaces(); // 3
          decimal result = ((int)original) + (((int)(original * Math.Pow(10, decimalPlaces)) / (Math.Pow(10, decimalPlaces));
          

          【讨论】:

          • 可能是因为它无法编译。你是用什么语言开发的?我刚才在 C# 中尝试了这个,但尝试将小数乘以双精度时出现错误。
          【解决方案8】:

          你想要什么格式的输出?

          如果您对字符串感到满意,请考虑以下 C# 代码:

          double num = 3.12345;
          num.ToString("G3");
          

          结果将是“3.12”。

          如果您使用的是 .NET,此链接可能有用。 http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

          我希望这会有所帮助....但除非您确定您使用的语言和您想要输出的格式,否则很难提出合适的解决方案。

          【讨论】:

          • 这对 OP 没有帮助,因为它会舍入数字,而不是截断。此外,"G" 格式的精度说明符是指总位数,而不仅仅是小数位数("F" 就是这样做的)
          【解决方案9】:

          你可以使用Math.Round:

          decimal rounded = Math.Round(2.22939393, 3); //Returns 2.229
          

          或者您可以将 ToString 与 N3 numeric format 一起使用。

          string roundedNumber = number.ToString("N3");
          

          编辑:由于您不想四舍五入,您可以轻松使用Math.Truncate

          Math.Truncate(2.22977777 * 1000) / 1000; //Returns 2.229
          

          【讨论】:

          • 不适用于第二个示例。我只是希望它被截断 - 而不是四舍五入。
          • 重申一下:+1 表示 Math.Truncate,-1 表示 Math.Round,这并不能解决所提出的问题。
          • Math.Truncate 如果你不乘除以 1000 也不会工作。截断基本上会删除最后的零。没有以小数位数为参数的 Math.Truncate。
          【解决方案10】:
          double d = 2.22977777;
          d = ( (double) ( (int) (d * 1000.0) ) ) / 1000.0 ;
          

          当然,如果您尝试截断舍入误差,这将不起作用,但它应该适用于您在示例中提供的值。请参阅this question 的前两个答案,详细了解为什么它有时不起作用。

          【讨论】:

          • 哇这一切只是为了缩短一个数字。
          • 看起来很多,但它做的工作比转换为字符串要少得多。 :)
          • 请注意,您可能会遇到舍入错误。
          • 你不应该得到比开始时更多的舍入误差。
          • 我认为使用十进制数据类型应该是通用的解决方案。
          猜你喜欢
          • 2011-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-09
          • 2011-12-27
          • 2015-07-30
          • 2019-07-13
          相关资源
          最近更新 更多