【问题标题】:Casting a double as an int, does it round or just strip digits?将 double 转换为 int,它是舍入还是仅去除数字?
【发布时间】:2012-10-28 19:59:23
【问题描述】:

使用双精度数进行一些计算,然后需要将其转换为 int。所以我有一个简单的问题,当将双倍说 7.5 转换为 int 时,它将返回 7。

这是四舍五入的结果还是只是小数点后的任何内容?

如果它是四舍五入的乘积,它是否智能,即 0.1 到 0.5 向下舍入,0.6 到 0.9 向上舍入?

干杯

【问题讨论】:

  • 快速实验一下就可以回答这个问题...
  • 为什么不明确说明(这样未来的程序员就不必怀疑)并使用Math.Floor 去除小数,然后进行转换?
  • @cosmicsafari 你可以从实验中学到很多东西。
  • @AnnL.:如果你想明确一点,你可以使用 Math.Truncate。
  • 我个人很高兴他问了这个问题,这样我就能很快找到答案。我有一种预感,它总是四舍五入,但我感谢这个问题的快速确认。实验很好,但这个问题为我省去了麻烦。

标签: c# casting int double rounding


【解决方案1】:

不四舍五入,只返回小数点前的整数部分。

参考(感谢RawlingExplicit Numeric Conversions Table

当您将双精度或浮点值转换为整数类型时,这 值朝零四舍五入到最接近的整数值。

您可以通过编写简单的测试自己尝试这样的简单问题。以下测试(使用NUnit)将通过,因此可以回答您的问题:

[Test]
public void Cast_float_to_int_will_not_round_but_truncate
{
    var x = 3.9f;
    Assert.That((int)x == 3); // <-- This will pass
}

【讨论】:

    【解决方案2】:

    简单的转换只是去掉小数点后的所有内容。要向上或向下舍入,您可以使用Math.Round() method。这将向上或向下舍入,并提供一个参数,说明如果中途该做什么。您还可以使用Math.Floor()Math.Ceiling() 方法在强制转换之前隐式向上或向下舍入。以下是一些示例:

    double num1 = 3.5;
    double num2 = 3.2;
    double num3 = 3.9;
    
    (int)num1 // returns 3;
    (int)num2 // returns 3;
    (int)num3 // returns 3 also;
    (int)Math.Round(num1) // returns 4
    (int)Math.Round(num2) // returns 3
    (int)Math.Round(num3) // returns 4
    (int)Math.Floor(num1) // returns 3
    (int)Math.Floor(num2) // returns 3
    (int)Math.Floor(num3) // returns 3
    (int)Math.Ceiling(num1) // returns 4
    (int)Math.Ceiling(num2) // returns 4;
    (int)Math.Ceiling(num3) // returns 4;
    

    【讨论】:

      【解决方案3】:

      这样的普通演员

      int number;
      double decimals = 7.8987;
      
      number = (int)decimals;
      

      将返回 number = 7。那是因为它只是跳过了最不重要的数字。如果您希望它正确舍入,您可以像这样使用 Math.Round()

      number = (int)Math.Round(number);
      

      这将返回数字 = 8。

      【讨论】:

        【解决方案4】:

        来自C# Language Specification

        unchecked 上下文中,转换始终成功,并且 如下进行。

        • 如果操作数的值为 NaN 或无穷大, 转换的结果是未指定的值 目的地类型。

        • 否则,源操作数向 零到最接近的整数值。如果这个整数值在 目标类型的范围,则此值是 转换。

        • 否则,转换的结果是 目标类型的未指定值。

        另请参阅 MSDN 上的 Explicit Numeric Conversions Table — Remarks

        【讨论】:

          【解决方案5】:

          不要误以为它会向下取整。它去掉小数点并纯粹返回双精度的整数部分。这对于负数很重要,因为从 2.75 向下取整会得到 2,但从 -2.75 向下取整会得到 -3。强制转换不会向下取整,因此 (int)2.75 给出 2,但 (int)-2.75 给出 -2。

          double positiveDouble = 2.75;
          double negativeDouble = -2.75;
          
          int positiveInteger = (int) positiveDouble;
          int negativeInteger = (int) negativeDouble;
          
          Console.WriteLine(positiveInteger + " = (int)" + positiveDouble);
          Console.WriteLine(negativeInteger + " = (int)" + negativeDouble);
          
          Console.ReadLine();
          
          //Output: 2 = (int)2.75
          //        -2 = (int)-2.75
          

          【讨论】:

            【解决方案6】:

            取整数部分

            double d = 0.9;
            System.Console.WriteLine((int)d);
            

            结果为 0

            【讨论】:

              【解决方案7】:

              如果它返回 7 作为 7.5 的两倍,那么它不是四舍五入,因为四舍五入规则会规定 5 及以上的任何值都向上舍入,而不是向下舍入。

              【讨论】:

              • 除非基础值不是 7.5 而是 7.49999999999,在这种情况下它可能会在屏幕上显示 7.5,但会舍入到 7。由于浮点精度问题,这类问题经常发生。 OP特别想知道这是否是他问题的真正原因。现在,它不是,但这是一个完全有效的担忧。通过将 7.7d 转换为 int 来测试代码几乎没有那么模棱两可。
              • @Servy(和 Brian) 此外,还有 double 数字,如 7.9999999999999991,其默认字符串表示形式为 "8",但使用强制转换语法将其截断为整数 7
              • 这应该是一条评论。
              猜你喜欢
              • 2016-05-23
              • 2012-05-04
              • 2011-11-10
              • 1970-01-01
              • 1970-01-01
              • 2012-01-13
              • 1970-01-01
              • 2015-01-22
              • 2011-05-10
              相关资源
              最近更新 更多