Math.Round 方法

定义

将值舍入到最接近的整数或指定的小数位数。

重载

Round(Double, Int32, MidpointRounding)

使用指定的舍入约定将双精度浮点值舍入为指定的小数位数。

Round(Decimal, Int32, MidpointRounding)

使用指定的舍入约定将十进制值舍入为指定的小数位数。

Round(Double, MidpointRounding)

使用指定的舍入约定将双精度浮点值舍入为整数。

Round(Double, Int32)

将双精度浮点值舍入到指定数量的小数位,并将中点值舍入到最接近的偶数。

Round(Decimal, Int32)

将小数值舍入到指定数量的小数位,并将中点值舍入到最接近的偶数。

Round(Double)

将双精度浮点值舍入到最接近的整数值,并将中点值舍入到最接近的偶数。

Round(Decimal)

将小数值舍入到最接近的整数值,并将中点值舍入到最接近的偶数。

Round(Decimal, MidpointRounding)

使用指定的舍入约定将十进制值舍入为整数。

示例

除了"备注"部分中的示例外,本文还包含演示 方法的以下重载 Math.Round 的示例:

Math.Round (Decimal)
Math.Round (Double)
Math.Round (Decimal、Int32)
Math.Round (Decimal、MidpointRounding)
Math.Round (Double、Int32)
Math.Round (Double、MidpointRounding)
Math.Round (Decimal、Int32、MidpointRounding)
Math.Round (Double、Int32、MidpointRounding)

注解

本部分内容:

我要调用哪种方法?

您可以使用下表来选择适当的舍入方法。 除了 Math.Round 方法之外,它还包含 Math.CeilingMath.Floor

功能 调用
使用舍入到最接近的约定将数字舍入到整数。 Round(Decimal)

- 或 -

Round(Double)
使用指定的舍入约定将数字舍入到整数。 Round(Decimal, MidpointRounding)

- 或 -

Round(Double, MidpointRounding)
使用舍入到最接近的约定,将数字舍入到指定的小数位数。 Round(Decimal, Int32)

- 或 -

Round(Double, Int32)
使用指定的舍入约定将数字舍入到指定的小数位数。 Round(Decimal, Int32, MidpointRounding)

- 或 -

Round(Double, Int32, MidpointRounding)
Single使用指定的舍入约定将值舍入到指定的小数位数,并将精度减至最小。 将转换 SingleDecimal ,并调用 Round(Decimal, Int32, MidpointRounding)
将数字舍入到指定的小数位数,同时最大程度地减少舍入点值中的精度问题。 调用实现 "大于或等于" 比较的舍入方法。 请参见 舍入和精度
将小数值舍入到大于小数值的整数。 例如,3.1 舍入为4。 Ceiling
将小数值舍入为小于小数值的整数。 例如,3.9 舍入为3。 Floor

中点值和舍入约定

舍入涉及到将具有指定精度的数值转换为精度较低的值。 例如,可以使用 Round(Double) 方法将3.4 的值舍入到3.0,并使用 Round(Double, Int32) 方法将3.579 值舍入到3.58。

在中点值中,结果中的最小有效位后的值在两个数字之间精确到了一半。 例如,如果要舍入为两位小数,3.47500 是中值,如果要将它舍入到整数,则7.500 是中值。 在这些情况下,如果使用舍入到最接近的策略,则在没有舍入约定的情况下,不能轻松地识别最接近的值。

Round方法支持两个用于处理中点值的舍入约定:

  • 远离零的舍入

    中值舍入到下一个数字,而不是零。 例如,3.75 舍入为3.8,3.85 舍入到3.9,-3.75 舍入到-3.8,-3.85 舍入到-3.9。 这种形式的舍入由 MidpointRounding.AwayFromZero 枚举成员表示。

  • 舍入到最接近的偶数或按下舍入

    中值舍入为最接近的偶数。 例如,3.75 和3.85 舍入为3.8,-3.75 和-3.85 舍入到-3.8。 这种形式的舍入由 MidpointRounding.ToEven 枚举成员表示。

备注

在 .NET Core 3.0 及更高版本中,可通过枚举获得三个附加的舍入策略 MidpointRounding 。 所有情况下都使用这些策略,而不只是将中点值作为 MidpointRounding.ToEvenMidpointRounding.AwayFromZero

远离零的舍入是最广泛的舍入形式,而舍入到最接近的是财务和统计操作的标准。 它符合 IEEE Standard 754,第4部分。 当在多个舍入操作中使用时,舍入为最接近的值,即使是按单一方向持续舍入点值导致的舍入误差。 在某些情况下,此舍入误差很重要。

下面的示例演示了一个方向上按一致舍入的点值导致的偏差。 该示例计算值数组的 true 平均值 Decimal ,然后使用两种约定来计算数组中的值的值。 在此示例中,如果舍入到最接近的是相同的,则为真正的平均值和结果。 但是,当从零开始舍入时产生的结果与 .05 (3.6 或从 true 平均值 ) %% 不同。

decimal[] values = { 1.15m, 1.25m, 1.35m, 1.45m, 1.55m, 1.65m };
decimal sum = 0;

// Calculate true mean.
foreach (var value in values)
    sum += value;

Console.WriteLine("True mean:     {0:N2}", sum / values.Length);

// Calculate mean with rounding away from zero.
sum = 0;
foreach (var value in values)
    sum += Math.Round(value, 1, MidpointRounding.AwayFromZero);

Console.WriteLine("AwayFromZero:  {0:N2}", sum / values.Length);

// Calculate mean with rounding to nearest.
sum = 0;
foreach (var value in values)
    sum += Math.Round(value, 1, MidpointRounding.ToEven);

Console.WriteLine("ToEven:        {0:N2}", sum / values.Length);

// The example displays the following output:
//       True mean:     1.40
//       AwayFromZero:  1.45
//       ToEven:        1.40
Dim values() As Decimal = {1.15D, 1.25D, 1.35D, 1.45D, 1.55D, 1.65D}
Dim sum As Decimal

' Calculate true mean.
For Each value In values
    sum += value
Next
Console.WriteLine("True mean:     {0:N2}", sum / values.Length)

' Calculate mean with rounding away from zero.
sum = 0
For Each value In values
    sum += Math.Round(value, 1, MidpointRounding.AwayFromZero)
Next
Console.WriteLine("AwayFromZero:  {0:N2}", sum / values.Length)

' Calculate mean with rounding to nearest.
sum = 0
For Each value In values
    sum += Math.Round(value, 1, MidpointRounding.ToEven)
Next
Console.WriteLine("ToEven:        {0:N2}", sum / values.Length)

' The example displays the following output:
'       True mean:     1.40
'       AwayFromZero:  1.45
'       ToEven:        1.40

默认情况下, Round 方法使用舍入到最接近的规则。 下表列出了方法的重载 Round 以及每个重载使用的舍入约定。

重载 舍入约定
Round(Decimal) ToEven
Round(Double) ToEven
Round(Decimal, Int32) ToEven
Round(Double, Int32) ToEven
Round(Decimal, MidpointRounding) mode 参数确定。
Round(Double, MidpointRounding) mode 参数确定
Round(Decimal, Int32, MidpointRounding) mode 参数确定
Round(Double, Int32, MidpointRounding) mode 参数确定

舍入和精度

若要确定舍入运算是否包含中点值, Round 方法会将原始值乘以 10 n,其中 n 是返回值中所需的小数位数,然后确定值的剩余小数部分是否大于或等于 .5。 这对于测试相等性稍有不同,如参考主题的 "测试相等性" 一节中所述 Double ,与浮点值的相等性测试是否存在问题,因为浮点格式的二进制表示形式和精度问题。 这意味着,由于精度丢失) ,数值的小数部分稍微小于 0.5 (将不会向上舍入。

以下示例演示了该问题。 它会重复将 .1 添加到11.0,并将结果舍入到最接近的整数。 11.5 应使用任一中点舍入约定舍入到 12 (ToEvenAwayFromZero) 。 但是,如示例的输出所示,它不会。 该示例使用 "R" 标准数字格式字符串 来显示浮点值的完整精度,并显示在重复添加时要舍入的值已丢失精度,并且它的值实际上是11.499999999999998 的。 由于499999999999998小于 .5,中间值舍入约定不起作用,并且值向下舍入。 如示例中所示,如果将常量值11.5 赋给变量,则不会出现此问题 Double

public static void Example()
{
    Console.WriteLine("{0,5} {1,20:R}  {2,12} {3,15}\n",
                      "Value", "Full Precision", "ToEven",
                      "AwayFromZero");
    double value = 11.1;
    for (int ctr = 0; ctr <= 5; ctr++)
        value = RoundValueAndAdd(value);

    Console.WriteLine();

    value = 11.5;
    RoundValueAndAdd(value);
}

private static double RoundValueAndAdd(double value)
{
    Console.WriteLine("{0,5:N1} {0,20:R}  {1,12} {2,15}",
                      value, Math.Round(value, MidpointRounding.ToEven),
                      Math.Round(value, MidpointRounding.AwayFromZero));
    return value + .1;
}

// The example displays the following output:
//       Value       Full Precision        ToEven    AwayFromZero
//
//        11.1                 11.1            11              11
//        11.2                 11.2            11              11
//        11.3   11.299999999999999            11              11
//        11.4   11.399999999999999            11              11
//        11.5   11.499999999999998            11              11
//        11.6   11.599999999999998            12              12
//
//        11.5                 11.5            12              12
Public Sub Example()
    Dim value As Double = 11.1

    Console.WriteLine("{0,5} {1,20:R}  {2,12} {3,15}",
                    "Value", "Full Precision", "ToEven",
                    "AwayFromZero")
    Console.WriteLine()
    For ctr As Integer = 0 To 5
        value = RoundValueAndAdd(value)
    Next
    Console.WriteLine()

    value = 11.5
    RoundValueAndAdd(value)
End Sub

Private Function RoundValueAndAdd(value As Double) As Double
    Console.WriteLine("{0,5:N1} {0,20:R}  {1,12} {2,15}",
                    value, Math.Round(value, MidpointRounding.ToEven),
                    Math.Round(value, MidpointRounding.AwayFromZero))
    Return value + 0.1
End Function

' The example displays the following output:
'       Value       Full Precision        ToEven    AwayFromZero
'       
'        11.1                 11.1            11              11
'        11.2                 11.2            11              11
'        11.3   11.299999999999999            11              11
'        11.4   11.399999999999999            11              11
'        11.5   11.499999999999998            11              11
'        11.6   11.599999999999998            12              12
'       
'        11.5                 11.5            12              12

在以下情况下,舍入点值中的精度问题最可能出现在其中:

  • 当小数值不能精确表示为浮点类型的二进制格式时。

  • 要舍入的值是从一个或多个浮点运算计算得出的。

  • 当要舍入的值是 Single 而不是 Double 或时 Decimal 。 有关详细信息,请参阅下一节 舍入和单精度浮点值

如果舍入操作缺少精度,则可以执行以下操作:

  • 如果舍入操作调用了舍入值的重载 Double ,则可以将更改 DoubleDecimal 值并调用舍入值的重载 Decimal 。 尽管 Decimal 数据类型也有问题的表示形式和损失,但这些问题远远不常见。

  • 定义一种自定义舍入算法,该算法执行 "将近相等" 测试来确定要舍入的值是否接近于中点值可接受。 下面的示例定义一个 RoundApproximate 方法,该方法检查小数值是否足以接近于中点舍入的中点值。 如示例的输出所示,它会更正上一个示例中显示的舍入问题。

    public static void Example()
    {
        Console.WriteLine("{0,5} {1,20:R}  {2,12} {3,15}\n",
                          "Value", "Full Precision", "ToEven",
                          "AwayFromZero");
        double value = 11.1;
        for (int ctr = 0; ctr <= 5; ctr++)
            value = RoundValueAndAdd(value);
    
        Console.WriteLine();
    
        value = 11.5;
        RoundValueAndAdd(value);
    }
    
    private static double RoundValueAndAdd(double value)
    {
        const double tolerance = 8e-14;
    
        Console.WriteLine("{0,5:N1} {0,20:R}  {1,12} {2,15}",
                          value,
                          RoundApproximate(value, 0, tolerance, MidpointRounding.ToEven),
                          RoundApproximate(value, 0, tolerance, MidpointRounding.AwayFromZero));
        return value + .1;
    }
    
    private static double RoundApproximate(double dbl, int digits, double margin,
                                      MidpointRounding mode)
    {
        double fraction = dbl * Math.Pow(10, digits);
        double value = Math.Truncate(fraction);
        fraction = fraction - value;
        if (fraction == 0)
            return dbl;
    
        double tolerance = margin * dbl;
        // Determine whether this is a midpoint value.
        if ((fraction >= .5 - tolerance) & (fraction <= .5 + tolerance))
        {
            if (mode == MidpointRounding.AwayFromZero)
                return (value + 1) / Math.Pow(10, digits);
            else
               if (value % 2 != 0)
                return (value + 1) / Math.Pow(10, digits);
            else
                return value / Math.Pow(10, digits);
        }
        // Any remaining fractional value greater than .5 is not a midpoint value.
        if (fraction > .5)
            return (value + 1) / Math.Pow(10, digits);
        else
            return value / Math.Pow(10, digits);
    }
    
    // The example displays the following output:
    //       Value       Full Precision        ToEven    AwayFromZero
    //
    //        11.1                 11.1            11              11
    //        11.2                 11.2            11              11
    //        11.3   11.299999999999999            11              11
    //        11.4   11.399999999999999            11              11
    //        11.5   11.499999999999998            12              12
    //        11.6   11.599999999999998            12              12
    //
    //        11.5                 11.5            12              12
    
    Public Sub Example()
        Dim value As Double = 11.1
    
        Console.WriteLine("{0,5} {1,20:R}  {2,12} {3,15}\n",
                        "Value", "Full Precision", "ToEven",
                        "AwayFromZero")
        For ctr As Integer = 0 To 5
            value = RoundValueAndAdd(value)
        Next
        Console.WriteLine()
    
        value = 11.5
        RoundValueAndAdd(value)
    End Sub
    
    Private Function RoundValueAndAdd(value As Double) As Double
        Const tolerance As Double = 0.00000000000008
        Console.WriteLine("{0,5:N1} {0,20:R}  {1,12} {2,15}",
                        value,
                        RoundApproximate(value, 0, tolerance, MidpointRounding.ToEven),
                        RoundApproximate(value, 0, tolerance, MidpointRounding.AwayFromZero))
        Return value + 0.1
    End Function
    
    Private Function RoundApproximate(dbl As Double, digits As Integer, margin As Double,
                                     mode As MidpointRounding) As Double
        Dim fraction As Double = dbl * Math.Pow(10, digits)
        Dim value As Double = Math.Truncate(fraction)
        fraction = fraction - value
        If fraction = 0 Then Return dbl
    
        Dim tolerance As Double = margin * dbl
        ' Determine whether this is a midpoint value.
        If (fraction >= 0.5 - tolerance) And (fraction <= 0.5 + tolerance) Then
            If mode = MidpointRounding.AwayFromZero Then
                Return (value + 1) / Math.Pow(10, digits)
            Else
                If value Mod 2 <> 0 Then
                    Return (value + 1) / Math.Pow(10, digits)
                Else
                    Return value / Math.Pow(10, digits)
                End If
            End If
        End If
        ' Any remaining fractional value greater than .5 is not a midpoint value.
        If fraction > 0.5 Then
            Return (value + 1) / Math.Pow(10, digits)
        Else
            Return value / Math.Pow(10, digits)
        End If
    End Function
    
    ' The example displays the following output:
    '       Value       Full Precision        ToEven    AwayFromZero
    '       
    '        11.1                 11.1            11              11
    '        11.2                 11.2            11              11
    '        11.3   11.299999999999999            11              11
    '        11.4   11.399999999999999            11              11
    '        11.5   11.499999999999998            12              12
    '        11.6   11.599999999999998            12              12
    '       
    '        11.5                 11.5            12              12
    

舍入和单精度浮点值

Round方法包含接受类型为和的参数的 Decimal 重载 Double 。 没有用于舍入类型的值的方法 Single 。 如果将值传递 Single 给方法的重载之一 Round ,则会将其转换为 c # 中的 () 或转换为 Visual Basic) 中的 (Double ,并 Round 调用具有参数的对应重载 Double 。 尽管这是一个扩大转换,但它通常会损失精度,如下面的示例所示。 如果将 Single 16.325 的值传递给 Round 方法,并使用舍入到最接近的约定舍入为两位小数位数,则结果为16.33,而不是预期的16.32 结果。

Single value = 16.325f;
Console.WriteLine("Widening Conversion of {0:R} (type {1}) to {2:R} (type {3}): ",
                  value, value.GetType().Name, (double)value,
                  ((double)(value)).GetType().Name);
Console.WriteLine(Math.Round(value, 2));
Console.WriteLine(Math.Round(value, 2, MidpointRounding.AwayFromZero));
Console.WriteLine();

Decimal decValue = (decimal)value;
Console.WriteLine("Cast of {0:R} (type {1}) to {2} (type {3}): ",
                  value, value.GetType().Name, decValue,
                  decValue.GetType().Name);
Console.WriteLine(Math.Round(decValue, 2));
Console.WriteLine(Math.Round(decValue, 2, MidpointRounding.AwayFromZero));

// The example displays the following output:
//    Widening Conversion of 16.325 (type Single) to 16.325000762939453 (type Double):
//    16.33
//    16.33
//
//    Cast of 16.325 (type Single) to 16.325 (type Decimal):
//    16.32
//    16.33
Dim value As Single = 16.325
Console.WriteLine("Widening Conversion of {0:R} (type {1}) to {2:R} (type {3}): ",
                value, value.GetType().Name, CDbl(value),
                CDbl(value).GetType().Name)
Console.WriteLine(Math.Round(value, 2))
Console.WriteLine(Math.Round(value, 2, MidpointRounding.AwayFromZero))
Console.WriteLine()

Dim decValue As Decimal = CDec(value)
Console.WriteLine("Cast of {0:R} (type {1}) to {2} (type {3}): ",
                value, value.GetType().Name, decValue,
                decValue.GetType().Name)
Console.WriteLine(Math.Round(decValue, 2))
Console.WriteLine(Math.Round(decValue, 2, MidpointRounding.AwayFromZero))
Console.WriteLine()

' The example displays the following output:
'    Widening Conversion of 16.325 (type Single) to 16.325000762939453 (type Double):
'    16.33
'    16.33
'    
'    Cast of 16.325 (type Single) to 16.325 (type Decimal):
'    16.32
'    16.33

此意外结果是由于值转换为 时精度 Single 损失 Double 。 由于生成的 Double 值 16.325000762939453 不是中点值,并且大于 16.325,因此它始终向上舍入。

在许多情况下,如示例所示,可以通过强制转换或将 值转换为 来最小化或消除精度 Single 损失 Decimal 。 请注意,由于这是收缩转换,因此需要使用强制转换运算符或调用转换方法。

Round(Double, Int32, MidpointRounding)

使用指定的舍入约定将双精度浮点值舍入为指定的小数位数。

public:
 static double Round(double value, int digits, MidpointRounding mode);
public static double Round (double value, int digits, MidpointRounding mode);
static member Round : double * int * MidpointRounding -> double
Public Shared Function Round (value As Double, digits As Integer, mode As MidpointRounding) As Double

参数

value
Double

要舍入的双精度浮点数。

digits
Int32

返回值中的小数数字。

mode
MidpointRounding

枚举值之一,指定要使用哪种舍入策略。

返回

Double

具有舍入 digits 到的小数 value 位数的数字。 如果 valuedigits 少部分数字,value 原样返回。

例外

digits 小于 0 或大于 15。

mode 不是 MidpointRounding 的一个有效值。

注解

参数的值 digits 的范围可以是 0 到 15。 类型支持的最大整数和小数位数 Double 为 15。

有关 使用中点值舍入 数字的信息,请参阅中点值和舍入约定。

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

如果参数的值为 value Double.NaN ,则方法返回 Double.NaN 。 如果 valueDouble.PositiveInfinityDouble.NegativeInfinity ,则方法将 Double.PositiveInfinity 分别返回 或 Double.NegativeInfinity

示例

下面的示例演示如何将 方法 Round(Double, Int32, MidpointRounding)MidpointRounding 枚举一起使用。


// Round a positive and a negative value using the default.
double result = Math.Round(3.45, 1);
Console.WriteLine($"{result,4} = Math.Round({3.45,5}, 1)");
result = Math.Round(-3.45, 1);
Console.WriteLine($"{result,4} = Math.Round({-3.45,5}, 1)\n");

// Round a positive value using a MidpointRounding value.
result = Math.Round(3.45, 1, MidpointRounding.ToEven);
Console.WriteLine($"{result,4} = Math.Round({3.45,5}, 1, MidpointRounding.ToEven)");
result = Math.Round(3.45, 1, MidpointRounding.AwayFromZero);
Console.WriteLine($"{result,4} = Math.Round({3.45,5}, 1, MidpointRounding.AwayFromZero)");
result = Math.Round(3.47, 1, MidpointRounding.ToZero);
Console.WriteLine($"{result,4} = Math.Round({3.47,5}, 1, MidpointRounding.ToZero)\n");

// Round a negative value using a MidpointRounding value.
result = Math.Round(-3.45, 1, MidpointRounding.ToEven);
Console.WriteLine($"{result,4} = Math.Round({-3.45,5}, 1, MidpointRounding.ToEven)");
result = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero);
Console.WriteLine($"{result,4} = Math.Round({-3.45,5}, 1, MidpointRounding.AwayFromZero)");
result = Math.Round(-3.47, 1, MidpointRounding.ToZero);
Console.WriteLine($"{result,4} = Math.Round({-3.47,5}, 1, MidpointRounding.ToZero)\n");

// The example displays the following output:

//         3.4 = Math.Round( 3.45, 1)
//         -3.4 = Math.Round(-3.45, 1)

//         3.4 = Math.Round(3.45, 1, MidpointRounding.ToEven)
//         3.5 = Math.Round(3.45, 1, MidpointRounding.AwayFromZero)
//         3.4 = Math.Round(3.47, 1, MidpointRounding.ToZero)

//         -3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
//         -3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)
//         -3.4 = Math.Round(-3.47, 1, MidpointRounding.ToZero)
Dim posValue As Double = 3.45
Dim negValue As Double = -3.45

' Round a positive and a negative value using the default.  
Dim result As Double = Math.Round(posValue, 1)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1)", result, posValue)
result = Math.Round(negValue, 1)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1)", result, negValue)
Console.WriteLine()

' Round a positive value using a MidpointRounding value. 
result = Math.Round(posValue, 1, MidpointRounding.ToEven)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToEven)",
                   result, posValue)
result = Math.Round(posValue, 1, MidpointRounding.AwayFromZero)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.AwayFromZero)",
                   result, posValue)
Console.WriteLine()

' Round a positive value using a MidpointRounding value. 
result = Math.Round(negValue, 1, MidpointRounding.ToEven)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToEven)",
                    result, negValue)
result = Math.Round(negValue, 1, MidpointRounding.AwayFromZero)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.AwayFromZero)",
                   result, negValue)
Console.WriteLine()

'This code example produces the following results:

'  3.4 = Math.Round( 3.45, 1)
' -3.4 = Math.Round(-3.45, 1)

' 3.4 = Math.Round( 3.45, 1, MidpointRounding.ToEven)
' 3.5 = Math.Round( 3.45, 1, MidpointRounding.AwayFromZero)

' -3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
' -3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)

调用方说明

由于将十进制值表示为浮点数或对浮点值执行算术运算可能会导致精度损失,因此在某些情况下, 方法可能不会显示为舍入参数指定的中点值。 Round(Double, Int32, MidpointRounding) mode 下面的示例对此进行说明,其中 2.135 舍入为 2.13 而不是 2.14。 这是因为在内部, 方法乘以 10 位数字,在这种情况下,乘法运算会丢失 value 精度。

:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.math.round/cs/round4.cs" interactive="try-dotnet-method" id="Snippet3 "::: ::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.math.round/vb/round4.vb" id="Snippet3":::

另请参阅

适用于

Round(Decimal, Int32, MidpointRounding)

使用指定的舍入约定将十进制值舍入为指定的小数位数。

public:
 static System::Decimal Round(System::Decimal d, int decimals, MidpointRounding mode);
public static decimal Round (decimal d, int decimals, MidpointRounding mode);
static member Round : decimal * int * MidpointRounding -> decimal
Public Shared Function Round (d As Decimal, decimals As Integer, mode As MidpointRounding) As Decimal

参数

d
Decimal

要舍入的小数。

decimals
Int32

返回值中的小数位数。

mode
MidpointRounding

枚举值之一,指定要使用哪种舍入策略。

返回

Decimal

decimals 数位数舍入 d 到的数字。 如果 ddecimals 少部分数字,d 原样返回。

例外

decimals 小于 0 或大于 28。

mode 不是 MidpointRounding 的一个有效值。

结果超出了 Decimal 的范围。

注解

有关 使用中点值舍入 数字的信息,请参阅中点值和舍入约定。

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

参数的值 decimals 的范围可以是 0 到 28。

示例

下面的示例演示如何将 方法 RoundMidpointRounding 枚举一起使用。

decimal result;

// Round a positive value using different strategies.
// The precision of the result is 1 decimal place.

result = Math.Round(3.45m, 1, MidpointRounding.ToEven);
Console.WriteLine($"{result} = Math.Round({3.45m}, 1, MidpointRounding.ToEven)");
result = Math.Round(3.45m, 1, MidpointRounding.AwayFromZero);
Console.WriteLine($"{result} = Math.Round({3.45m}, 1, MidpointRounding.AwayFromZero)");
result = Math.Round(3.47m, 1, MidpointRounding.ToZero);
Console.WriteLine($"{result} = Math.Round({3.47m}, 1, MidpointRounding.ToZero)\n");

// Round a negative value using different strategies.
// The precision of the result is 1 decimal place.

result = Math.Round(-3.45m, 1, MidpointRounding.ToEven);
Console.WriteLine($"{result} = Math.Round({-3.45m}, 1, MidpointRounding.ToEven)");
result = Math.Round(-3.45m, 1, MidpointRounding.AwayFromZero);
Console.WriteLine($"{result} = Math.Round({-3.45m}, 1, MidpointRounding.AwayFromZero)");
result = Math.Round(-3.47m, 1, MidpointRounding.ToZero);
Console.WriteLine($"{result} = Math.Round({-3.47m}, 1, MidpointRounding.ToZero)\n");

/*
This code example produces the following results:

3.4 = Math.Round(3.45, 1, MidpointRounding.ToEven)
3.5 = Math.Round(3.45, 1, MidpointRounding.AwayFromZero)
3.4 = Math.Round(3.47, 1, MidpointRounding.ToZero)

-3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
-3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)
-3.4 = Math.Round(-3.47, 1, MidpointRounding.ToZero)
*/
Dim result As Decimal = 0D
Dim posValue As Decimal = 3.45D
Dim negValue As Decimal = -3.45D

' Round a positive value using different strategies.
' The precision of the result is 1 decimal place.
result = Math.Round(posValue, 1, MidpointRounding.ToEven)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToEven)",
                   result, posValue)
result = Math.Round(posValue, 1, MidpointRounding.AwayFromZero)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.AwayFromZero)",
                   result, posValue)
result = Math.Round(posValue, 1, MidpointRounding.ToZero)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToZero)",
                   result, posValue)
Console.WriteLine()

' Round a negative value using different strategies.
' The precision of the result is 1 decimal place.
result = Math.Round(negValue, 1, MidpointRounding.ToEven)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToEven)",
                    result, negValue)
result = Math.Round(negValue, 1, MidpointRounding.AwayFromZero)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.AwayFromZero)",
                   result, negValue)
result = Math.Round(negValue, 1, MidpointRounding.ToZero)
Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToZero)",
                   result, negValue)
Console.WriteLine()

'This code example produces the following results:
'
'        3.4 = Math.Round(3.45, 1, MidpointRounding.ToEven)
'        3.5 = Math.Round(3.45, 1, MidpointRounding.AwayFromZero)
'        3.4 = Math.Round(3.45, 1, MidpointRounding.ToZero)
'
'        -3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
'        -3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)
'        -3.4 = Math.Round(-3.45, 1, MidpointRounding.ToZero)
'

另请参阅

适用于

Round(Double, MidpointRounding)

使用指定的舍入约定将双精度浮点值舍入为整数。

public:
 static double Round(double value, MidpointRounding mode);
public static double Round (double value, MidpointRounding mode);
static member Round : double * MidpointRounding -> double
Public Shared Function Round (value As Double, mode As MidpointRounding) As Double

参数

value
Double

要舍入的双精度浮点数。

mode
MidpointRounding

枚举值之一,指定要使用哪种舍入策略。

返回

Double

舍入 value 到的整数。 此方法返回 Double ,而不是整型类型。

例外

mode 不是 MidpointRounding 的一个有效值。

注解

有关 使用中点值舍入 数字的信息,请参阅中点值和舍入约定。

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

如果参数的值为 value Double.NaN ,则方法返回 Double.NaN 。 如果 valueDouble.PositiveInfinityDouble.NegativeInfinity ,则方法将 Double.PositiveInfinity 分别返回 或 Double.NegativeInfinity

示例

以下示例显示 方法返回 Round(Double, MidpointRounding) 的值,这些值 mode 不同。

Double[] values = { 12.0, 12.1, 12.2, 12.3, 12.4, 12.5, 12.6,
                  12.7, 12.8, 12.9, 13.0 };
Console.WriteLine($"{"Value",-10} {"Default",-10} {"ToEven",-10} {"AwayFromZero",-15} {"ToZero",-15}");

foreach (var value in values)
    Console.WriteLine($"{value,-10:R} {Math.Round(value),-10} " +
        $"{Math.Round(value, MidpointRounding.ToEven),-10} " +
        $"{Math.Round(value, MidpointRounding.AwayFromZero),-15} " +
        $"{Math.Round(value, MidpointRounding.ToZero),-15}");

// The example displays the following output:
//       Value      Default    ToEven     AwayFromZero    ToZero
//       12         12         12         12              12
//       12.1       12         12         12              12
//       12.2       12         12         12              12
//       12.3       12         12         12              12
//       12.4       12         12         12              12
//       12.5       12         12         13              12
//       12.6       13         13         13              12
//       12.7       13         13         13              12
//       12.8       13         13         13              12
//       12.9       13         13         13              12
//       13         13         13         13              13
Dim values() As Double = {12.0, 12.1, 12.2, 12.3, 12.4, 12.5, 12.6,
                         12.7, 12.8, 12.9, 13.0}
Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-15} {4,-15}", "Value", "Default",
                "ToEven", "AwayFromZero", "ToZero")
For Each value In values
    Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-15} {4,-15}",
                   value, Math.Round(value),
                   Math.Round(value, MidpointRounding.ToEven),
                   Math.Round(value, MidpointRounding.AwayFromZero),
                   Math.Round(value, MidpointRounding.ToZero))
Next

' The example displays the following output:
'       Value      Default    ToEven     AwayFromZero     ToZero
'       12         12         12         12               12
'       12.1       12         12         12               12
'       12.2       12         12         12               12
'       12.3       12         12         12               12
'       12.4       12         12         12               12
'       12.5       12         12         13               12
'       12.6       13         13         13               12
'       12.7       13         13         13               12
'       12.8       13         13         13               12
'       12.9       13         13         13               12
'       13         13         13         13               13

调用方说明

由于将十进制值表示为浮点数或对浮点值执行算术运算可能会导致精度损失,因此在某些情况下, 方法可能不会将中点值舍入到最接近的均匀 Round(Double, MidpointRounding) 整数。 在下面的示例中,由于浮点值 .1 没有有限的二进制表示形式,因此对值为 11.5 的方法的第一次调用将返回 Round(Double) 11 而不是 12。

:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.math.round/cs/round5.cs" interactive="try-dotnet" id="Snippet4"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.math.round/vb/round5.vb" id="Snippet4":::

另请参阅

适用于

Round(Double, Int32)

将双精度浮点值舍入到指定数量的小数位,并将中点值舍入到最接近的偶数。

public:
 static double Round(double value, int digits);
public static double Round (double value, int digits);
static member Round : double * int -> double
Public Shared Function Round (value As Double, digits As Integer) As Double

参数

value
Double

要舍入的双精度浮点数。

digits
Int32

返回值中的小数数字。

返回

Double

最接近 valuedigits 位小数的数字。

例外

digits 小于 0 或大于 15。

注解

参数的值 digits 的范围可以是 0 到 15。 类型支持的最大整数和小数位数 Double 为 15。

此方法使用 的默认舍入约定 MidpointRounding.ToEven 。 有关 使用中点值舍入 数字的信息,请参阅中点值和舍入约定。

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

如果参数的值为 value Double.NaN ,则方法返回 Double.NaN 。 如果 valueDouble.PositiveInfinityDouble.NegativeInfinity ,则方法将 Double.PositiveInfinity 分别返回 或 Double.NegativeInfinity

示例

以下示例将包含两个小数位数的双精度值舍入为具有单个小数位数的双精度值。

Math::Round(3.44, 1); //Returns 3.4.
Math::Round(3.45, 1); //Returns 3.4.
Math::Round(3.46, 1); //Returns 3.5.

Math::Round(4.34, 1); // Returns 4.3
Math::Round(4.35, 1); // Returns 4.4
Math::Round(4.36, 1); // Returns 4.4
Math.Round(3.44, 1); //Returns 3.4.
Math.Round(3.45, 1); //Returns 3.4.
Math.Round(3.46, 1); //Returns 3.5.

Math.Round(4.34, 1); // Returns 4.3
Math.Round(4.35, 1); // Returns 4.4
Math.Round(4.36, 1); // Returns 4.4
Math.Round(3.44, 1) 'Returns 3.4.
Math.Round(3.45, 1) 'Returns 3.4.
Math.Round(3.46, 1) 'Returns 3.5.

Math.Round(4.34, 1) ' Returns 4.3
Math.Round(4.35, 1) ' Returns 4.4
Math.Round(4.36, 1) ' Returns 4.4

调用方说明

由于将十进制值表示为浮点数或对浮点值执行算术运算可能会导致精度损失,因此在某些情况下, 方法可能不会将中点值舍入到小数位置中最接近的均匀值。 Round(Double, Int32) digits 下面的示例对此进行说明,其中 2.135 舍入为 2.13 而不是 2.14。 这是因为在内部, 方法乘以 10 位数字,在这种情况下,乘法运算会丢失 value 精度。

:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.math.round/cs/round3.cs" interactive="try-dotnet" id="Snippet2 "::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.math.round/vb/round3.vb" id="Snippet2":::

另请参阅

适用于

Round(Decimal, Int32)

将小数值舍入到指定数量的小数位,并将中点值舍入到最接近的偶数。

public:
 static System::Decimal Round(System::Decimal d, int decimals);
public static decimal Round (decimal d, int decimals);
static member Round : decimal * int -> decimal
Public Shared Function Round (d As Decimal, decimals As Integer) As Decimal

参数

d
Decimal

要舍入的小数。

decimals
Int32

返回值中的小数位数。

返回

Decimal

最接近 ddecimals 位小数的数字。

例外

decimals 小于 0 或大于 28。

结果超出了 Decimal 的范围。

注解

参数的值 decimals 的范围可以是 0 到 28。

此方法使用 的默认舍入约定 MidpointRounding.ToEven 。 有关使用中点值舍入数字的信息,请参阅中点 值和舍入约定

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

示例

以下示例将具有两个小数位数的十进制值舍入为具有单个小数位数的值。

Console.WriteLine(Math.Round(3.44m, 1));
Console.WriteLine(Math.Round(3.45m, 1));
Console.WriteLine(Math.Round(3.46m, 1));
Console.WriteLine();

Console.WriteLine(Math.Round(4.34m, 1));
Console.WriteLine(Math.Round(4.35m, 1));
Console.WriteLine(Math.Round(4.36m, 1));

// The example displays the following output:
//       3.4
//       3.4
//       3.5
//
//       4.3
//       4.4
//       4.4
Console.WriteLine(Math.Round(3.44, 1))
Console.WriteLine(Math.Round(3.45, 1))
Console.WriteLine(Math.Round(3.46, 1))
Console.WriteLine()

Console.WriteLine(Math.Round(4.34, 1))
Console.WriteLine(Math.Round(4.35, 1))
Console.WriteLine(Math.Round(4.36, 1))

' The example displays the following output:
'       3.4
'       3.4
'       3.5
'       
'       4.3
'       4.4
'       4.4

另请参阅

适用于

Round(Double)

将双精度浮点值舍入到最接近的整数值,并将中点值舍入到最接近的偶数。

public:
 static double Round(double a);
public static double Round (double a);
static member Round : double -> double
Public Shared Function Round (a As Double) As Double

参数

a
Double

要舍入的双精度浮点数。

返回

Double

最接近 a 的整数。 如果 a 的小数部分正好处于两个整数中间,其中一个整数为偶数,另一个整数为奇数,则返回偶数。 请注意,此方法返回 Double,而不是整数类型。

注解

此方法使用 的默认舍入约定 MidpointRounding.ToEven 。 有关使用中点值舍入数字的信息,请参阅中点 值和舍入约定

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

如果参数的值为 a Double.NaN ,则方法返回 Double.NaN 。 如果 aDouble.PositiveInfinityDouble.NegativeInfinity ,则方法将 Double.PositiveInfinity 分别返回 或 Double.NegativeInfinity

从 Visual Basic 15.8 开始,如果将 方法返回的值传递给任何整型转换函数 ,或者将 返回的 Double 值自动转换为 Option Strict 设置为 Off 的整数,则优化双对整数转换 Round Round 的性能。 此优化使代码可以更快运行 -- 对于进行大量到整型类型的转换的代码,可快达两倍。 以下示例演示了此类优化转换:

Dim d1 As Double = 1043.75133
Dim i1 As Integer = CInt(Math.Ceiling(d1))        ' Result: 1044

Dim d2 As Double = 7968.4136
Dim i2 As Integer = CInt(Math.Ceiling(d2))        ' Result: 7968

示例

下面的示例演示如何舍入到最接近的整数值。

using namespace System;

void main()
{
    Console::WriteLine("Classic Math.Round in CPP");
    Console::WriteLine(Math::Round(4.4));     // 4
    Console::WriteLine(Math::Round(4.5));     // 4
    Console::WriteLine(Math::Round(4.6));     // 5
    Console::WriteLine(Math::Round(5.5));     // 6
}
Console.WriteLine("Classic Math.Round in CSharp");
Console.WriteLine(Math.Round(4.4)); // 4
Console.WriteLine(Math.Round(4.5)); // 4
Console.WriteLine(Math.Round(4.6)); // 5
Console.WriteLine(Math.Round(5.5)); // 6
Module Module1

    Sub Main()
    Console.WriteLine("Classic Math.Round in Visual Basic")
    Console.WriteLine(Math.Round(4.4)) ' 4
    Console.WriteLine(Math.Round(4.5)) ' 4
    Console.WriteLine(Math.Round(4.6)) ' 5
    Console.WriteLine(Math.Round(5.5)) ' 6
    End Sub

End Module

调用方说明

由于将十进制值表示为浮点数或对浮点值执行算术运算可能会导致精度损失,因此在某些情况下, 方法可能不会将中点值舍入到最接近的均匀 Round(Double) 整数。 在下面的示例中,由于浮点值 .1 没有有限的二进制表示形式,因此对值为 11.5 的方法的第一次调用将返回 Round(Double) 11 而不是 12。

:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.math.round/cs/round2.cs" interactive="try-dotnet" id="Snippet1" ::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.math.round/vb/round2.vb" id="Snippet1":::

另请参阅

适用于

Round(Decimal)

将小数值舍入到最接近的整数值,并将中点值舍入到最接近的偶数。

public:
 static System::Decimal Round(System::Decimal d);
public static decimal Round (decimal d);
static member Round : decimal -> decimal
Public Shared Function Round (d As Decimal) As Decimal

参数

d
Decimal

要舍入的小数。

返回

Decimal

最接近 d 参数的整数。 如果 d 的小数部分正好处于两个整数中间,其中一个整数为偶数,另一个整数为奇数,则返回偶数。 请注意,此方法返回 Decimal,而不是整数类型。

例外

结果超出了 Decimal 的范围。

示例

下面的示例演示 Round(Decimal) 方法。 4.5 的值舍入为 4 而不是 Decimal 5,因为此重载使用默认 ToEven 约定。

for (decimal value = 4.2m; value <= 4.8m; value+=.1m )
   Console.WriteLine("{0} --> {1}", value, Math.Round(value));
// The example displays the following output:
//       4.2 --> 4
//       4.3 --> 4
//       4.4 --> 4
//       4.5 --> 4
//       4.6 --> 5
//       4.7 --> 5
//       4.8 --> 5
Module Example
   Public Sub Main()
      For value As Decimal = 4.2d To 4.8d Step .1d
         Console.WriteLine("{0} --> {1}", value, Math.Round(value))
      Next   
   End Sub                                                                 
End Module
' The example displays the following output:
'       4.2 --> 4
'       4.3 --> 4
'       4.4 --> 4
'       4.5 --> 4
'       4.6 --> 5
'       4.7 --> 5
'       4.8 --> 5

注解

此方法使用 的默认舍入约定 MidpointRounding.ToEven 。 有关使用中点值舍入数字的信息,请参阅中点 值和舍入约定

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

另请参阅

适用于

Round(Decimal, MidpointRounding)

使用指定的舍入约定将十进制值舍入为整数。

public:
 static System::Decimal Round(System::Decimal d, MidpointRounding mode);
public static decimal Round (decimal d, MidpointRounding mode);
static member Round : decimal * MidpointRounding -> decimal
Public Shared Function Round (d As Decimal, mode As MidpointRounding) As Decimal

参数

d
Decimal

要舍入的小数。

mode
MidpointRounding

枚举值之一,指定要使用哪种舍入策略。

返回

Decimal

舍入 d 到的整数。 此方法返回 Decimal ,而不是整型类型。

例外

mode 不是 MidpointRounding 的一个有效值。

结果超出了 Decimal 的范围。

注解

有关使用中点值舍入数字的信息,请参阅中点 值和舍入约定

重要

在舍入中点值时,舍入算法执行相等测试。 由于浮点格式存在的二进制表示和精度问题,因此方法返回的值可能异常。 有关详细信息,请参阅舍入 和精度

示例

以下示例显示 方法返回 Round(Decimal, MidpointRounding) 的值,这些值 mode 不同。

Console.WriteLine($"{"Value",-10} {"Default",-10} {"ToEven",-10} {"AwayFromZero",-15} {"ToZero",-15}");
for (decimal value = 12.0m; value <= 13.0m; value += 0.1m)
    Console.WriteLine($"{value,-10} {Math.Round(value),-10} " +
        $"{Math.Round(value, MidpointRounding.ToEven),-10} " +
        $"{Math.Round(value, MidpointRounding.AwayFromZero),-15} " +
        $"{Math.Round(value, MidpointRounding.ToZero),-15}");

// The example displays the following output:
//       Value      Default    ToEven     AwayFromZero    ToZero
//       12.0       12         12         12              12
//       12.1       12         12         12              12
//       12.2       12         12         12              12
//       12.3       12         12         12              12
//       12.4       12         12         12              12
//       12.5       12         12         13              12
//       12.6       13         13         13              12
//       12.7       13         13         13              12
//       12.8       13         13         13              12
//       12.9       13         13         13              12
//       13.0       13         13         13              13
Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-15} {4,-15}", "Value", "Default",
                "ToEven", "AwayFromZero", "ToZero")
For value As Decimal = 12D To 13D Step 0.1D
    Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-15} {4,-15}",
                   value, Math.Round(value),
                   Math.Round(value, MidpointRounding.ToEven),
                   Math.Round(value, MidpointRounding.AwayFromZero),
                   Math.Round(value, MidpointRounding.ToZero))
Next

' The example displays the following output:
'       Value      Default    ToEven     AwayFromZero     ToZero
'       12         12         12         12               12
'       12.1       12         12         12               12
'       12.2       12         12         12               12
'       12.3       12         12         12               12
'       12.4       12         12         12               12
'       12.5       12         12         13               12
'       12.6       13         13         13               12
'       12.7       13         13         13               12
'       12.8       13         13         13               12
'       12.9       13         13         13               12
'       13.0       13         13         13               13

另请参阅

适用于