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 方法,它还包括 Math.CeilingMath.Floor

Call
使用舍入到最接近的约定将数字舍入为整数。 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使用指定的舍入约定将值舍入为指定的小数位数,并最大程度地减少精度损失。 Single将转换为Decimal和调用Round(Decimal, Int32, MidpointRounding)
将数字舍入为指定的小数位数,同时最大程度地减少舍入中点值的精度问题。 调用实现“大于或近似等于”比较的舍入方法。 请参阅 舍入和精度
将小数点值舍入为大于小数值的整数。 例如,第 3.1 到 4 轮。 Ceiling
将小数点值舍入为小于小数值的整数。 例如,第 3.9 到 3 轮。 Floor

中点值和舍入约定

舍入涉及将具有指定精度的数值转换为精度较低的值。 例如,可以使用 Round(Double) 该方法将值 3.4 舍入为 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 枚举成员表示。

Note

在 .NET Core 3.0 及更高版本中,可通过 MidpointRounding 枚举获取另外三个舍入策略。 这些策略在所有情况下都使用,而不仅仅是中点值和中MidpointRounding.AwayFromZero点值MidpointRounding.ToEven

从零舍入是最广为人知的舍入形式,而舍入到最接近的甚至是金融和统计操作的标准。 它符合 IEEE 标准 754 第 4 节。 在多个舍入操作中使用时,舍入到最接近甚至会减少由一个方向一致舍入中点值导致的舍入错误。 在某些情况下,此舍入错误可能很重要。

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

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
open System

let values = [| 1.15m; 1.25m; 1.35m; 1.45m; 1.55m; 1.65m |]
let mutable sum = 0m

// Calculate true mean.
for value in values do
    sum <- sum + value

printfn $"True mean:     {sum / decimal values.Length:N2}"

// Calculate mean with rounding away from zero.
sum <- 0m
for value in values do
    sum <- sum + Math.Round(value, 1, MidpointRounding.AwayFromZero)

printfn $"AwayFromZero:  {sum / decimal values.Length:N2}"

// Calculate mean with rounding to nearest.
sum <- 0m
for value in values do
    sum <- sum + Math.Round(value, 1, MidpointRounding.ToEven)

printfn $"ToEven:        {sum / decimal values.Length:N2}"

// 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 重载和每个使用的舍入约定。

Overload 舍入约定
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 将原始值乘以 10n,其中 n 是返回值中所需的小数位数,然后确定该值的剩余小数部分是否大于或等于 .5。 这是对相等性测试的轻微变化,如参考主题的 Double “相等测试”部分所述,由于浮点格式存在二进制表示和精度问题,对浮点值的相等性测试存在问题。 这意味着,任何略小于 .5 的数字的小数部分(由于精度损失)都不会向上舍入。

下面的示例演示了问题。 它反复将 .1 添加到 11.0,并将结果舍入到最接近的整数。 11.5 应使用中点舍入约定(ToEvenAwayFromZero) 舍入到 12。 但是,如示例中的输出所示,它不会。 该示例使用“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
open System

let roundValueAndAdd (value: double) =
    printfn $"{value,5:N1} {value,20:R}  {Math.Round(value, MidpointRounding.ToEven),12} {Math.Round(value, MidpointRounding.AwayFromZero),15}"
    value + 0.1

printfn "%5s %20s  %12s %15s\n" "Value" "Full Precision" "ToEven" "AwayFromZero"
let mutable value = 11.1
for _ = 0 to 5 do
    value <- roundValueAndAdd value

printfn ""

value <- 11.5
roundValueAndAdd value
|> ignore

// 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 而不是一个 DoubleDecimal。 有关详细信息,请参阅下一部分: 舍入和单精度浮点值

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

  • 如果舍入操作调用舍入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
    
    open System
    
    let roundApproximate dbl digits margin mode =
        let fraction = dbl * Math.Pow(10, digits)
        let value = Math.Truncate fraction
        let fraction = fraction - value
        if fraction = 0 then
            dbl
        else
            let tolerance = margin * dbl
            // Determine whether this is a midpoint value.
            if (fraction >= 0.5 - tolerance) && (fraction <= 0.5 + tolerance) then
                if mode = MidpointRounding.AwayFromZero then
                    (value + 1.) / Math.Pow(10, digits)
                elif value % 2. <> 0 then
                    (value + 1.) / Math.Pow(10, digits)
                else
                    value / Math.Pow(10, digits)
            // Any remaining fractional value greater than .5 is not a midpoint value.
            elif fraction > 0.5 then
                (value + 1.) / Math.Pow(10, digits)
            else
                value / Math.Pow(10, digits)
    
    
    let roundValueAndAdd value =
        let tolerance = 8e-14
        let round = roundApproximate value 0 tolerance
    
        printfn $"{value,5:N1} {value,20:R}  {round MidpointRounding.ToEven,12} {round MidpointRounding.AwayFromZero,15}"
        value + 0.1
    
    printfn "%5s %20s  %12s %15s\n" "Value" "Full Precision" "ToEven" "AwayFromZero"
    let mutable value = 11.1
    for _ = 0 to 5 do
        value <- roundValueAndAdd value
    
    printfn ""
    
    value <- 11.5
    roundValueAndAdd value 
    |> ignore
    
    // 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 方法的重载之一,则会将Double Visual Basic转换为 Double,并调用具有 Double 参数的相应 Round 重载。 虽然这是一个扩大的转换,但它通常涉及精度损失,如以下示例所示。 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
// In F#, 'float', 'float64', and 'double' are aliases for System.Double...
// 'float32' and 'single' are aliases for System.Single
open System

let value = 16.325f
printfn $"Widening Conversion of {value:R} (type {value.GetType().Name}) to {double value:R} (type {(double value).GetType().Name}): "
printfn $"{Math.Round(decimal value, 2)}"
printfn $"{Math.Round(decimal value, 2, MidpointRounding.AwayFromZero)}"
printfn ""

let decValue = decimal value
printfn $"Cast of {value:R} (type {value.GetType().Name}) to {decValue} (type {decValue.GetType().Name}): "
printfn $"{Math.Round(decValue, 2)}"
printfn $"{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 a Double的精度损失。 由于生成的 Double 值为 16.325000762939453 不是中点值,并且大于 16.325,因此始终向上舍入。

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

Round(Double, Int32, MidpointRounding)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

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

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

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

返回

包含 digits 舍入为的小数位数 value 的数字。 如果 value 小数位数少于 digitsvalue 则返回不变。

例外

digits 小于 0 或大于 15。

mode 不是有效值 MidpointRounding

注解

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

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

重要

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

如果参数的值为value,则该方法返回 Double.NaNDouble.NaN 如果 valueDouble.PositiveInfinityDouble.NegativeInfinity,则该方法分别返回 Double.PositiveInfinityDouble.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)
// Round a positive and a negative value using the default.
let result = Math.Round(3.45, 1)
printfn $"{result,4} = Math.Round({3.45,5}, 1)"
let result = Math.Round(-3.45, 1)
printfn $"{result,4} = Math.Round({-3.45,5}, 1)\n"

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

// Round a negative value using a MidpointRounding value.
let result = Math.Round(-3.45, 1, MidpointRounding.ToEven)
printfn $"{result,4} = Math.Round({-3.45,5}, 1, MidpointRounding.ToEven)"
let result = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)
printfn $"{result,4} = Math.Round({-3.45,5}, 1, MidpointRounding.AwayFromZero)"
let result = Math.Round(-3.47, 1, MidpointRounding.ToZero)
printfn $"{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。 之所以发生这种情况,是因为该方法在内部乘 value 以 10,在这种情况下,乘法运算会丢失精度。

double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 };
foreach (double value in values)
   Console.WriteLine("{0} --> {1}", value,
                     Math.Round(value, 2, MidpointRounding.AwayFromZero));

// The example displays the following output:
//       2.125 --> 2.13
//       2.135 --> 2.13
//       2.145 --> 2.15
//       3.125 --> 3.13
//       3.135 --> 3.14
//       3.145 --> 3.15
open System

let values = [| 2.125; 2.135; 2.145; 3.125; 3.135; 3.145 |]
for value in values do
    printfn $"{value} --> {Math.Round(value, 2, MidpointRounding.AwayFromZero)}"
// The example displays the following output:
//       2.125 --> 2.13
//       2.135 --> 2.13
//       2.145 --> 2.15
//       3.125 --> 3.13
//       3.135 --> 3.14
//       3.145 --> 3.15
Module Example
   Public Sub Main()
      Dim values() As Double = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 }
      For Each value As Double In values
         Console.WriteLine("{0} --> {1}", value, 
                           Math.Round(value, 2, MidpointRounding.AwayFromZero))
      Next
   End Sub
End Module
' The example displays the following output:
'       2.125 --> 2.13
'       2.135 --> 2.13
'       2.145 --> 2.15
'       3.125 --> 3.13
'       3.135 --> 3.14
'       3.145 --> 3.15

另请参阅

适用于

Round(Decimal, Int32, MidpointRounding)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

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

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

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

返回

包含 decimals 舍入为的小数位数 d 的数字。 如果 d 小数位数少于 decimalsd 则返回不变。

例外

decimals 小于 0 或大于 28。

mode 不是有效值 MidpointRounding

结果不在一个 Decimal范围之外。

注解

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

重要

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

参数的值 decimals 可以介于 0 到 28 范围内。

示例

以下示例演示如何将 Round 该方法与枚举一起使用 MidpointRounding

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)
*/
// Round a positive value using different strategies.
// The precision of the result is 1 decimal place.

let result = Math.Round(3.45m, 1, MidpointRounding.ToEven)
printfn $"{result} = Math.Round({3.45m}, 1, MidpointRounding.ToEven)"
let result = Math.Round(3.45m, 1, MidpointRounding.AwayFromZero)
printfn $"{result} = Math.Round({3.45m}, 1, MidpointRounding.AwayFromZero)"
let result = Math.Round(3.47m, 1, MidpointRounding.ToZero)
printfn $"{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.

let result = Math.Round(-3.45m, 1, MidpointRounding.ToEven)
printfn $"{result} = Math.Round({-3.45m}, 1, MidpointRounding.ToEven)"
let result = Math.Round(-3.45m, 1, MidpointRounding.AwayFromZero)
printfn $"{result} = Math.Round({-3.45m}, 1, MidpointRounding.AwayFromZero)"
let result = Math.Round(-3.47m, 1, MidpointRounding.ToZero)
printfn $"{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)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

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

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

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

返回

舍入为的 value 整数。 此方法返回一个 Double 而不是整型类型。

例外

mode 不是有效值 MidpointRounding

注解

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

重要

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

如果参数的值为value,则该方法返回 Double.NaNDouble.NaN 如果 valueDouble.PositiveInfinityDouble.NegativeInfinity,则该方法分别返回 Double.PositiveInfinityDouble.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
open System

let values = 
    [| 12.; 12.1; 12.2; 12.3; 12.4; 12.5
       12.6; 12.7; 12.8; 12.9; 13. |]

printfn "%-10s %-10s %-10s %-15s %-15s" "Value" "Default" "ToEven" "AwayFromZero" "ToZero"

for value in values do
    $"{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}"
    |> printfn "%s"
    
// 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。

using System;

public class Example
{
   public static void Main()
   {
      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} --> {1}", value, Math.Round(value,
                        MidpointRounding.AwayFromZero));
      return value + .1;
   }
}
// The example displays the following output:
//       11.1 --> 11
//       11.2 --> 11
//       11.3 --> 11
//       11.4 --> 11
//       11.5 --> 11
//       11.6 --> 12
//
//       11.5 --> 12
open System

let roundValueAndAdd (value: float) =
      printfn $"{value} --> {Math.Round(value, MidpointRounding.AwayFromZero)}"
      value + 0.1

let mutable value = 11.1
for _ = 0 to 5 do
    value <- roundValueAndAdd value

printfn ""

value <- 11.5
roundValueAndAdd value
|> ignore

// The example displays the following output:
//       11.1 --> 11
//       11.2 --> 11
//       11.3 --> 11
//       11.4 --> 11
//       11.5 --> 11
//       11.6 --> 12
//
//       11.5 --> 12
Module Example
   Public Sub Main()
      Dim value As Double = 11.1
      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} --> {1}", value, Math.Round(value, 
                        MidpointRounding.AwayFromZero))
      Return value + .1
   End Function   
End Module
' The example displays the following output:
'       11.1 --> 11
'       11.2 --> 11
'       11.3 --> 11
'       11.4 --> 11
'       11.5 --> 11
'       11.6 --> 12
'       
'       11.5 --> 12

另请参阅

适用于

Round(Double, Int32)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

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

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

返回值中的小数位数。

返回

最接近 value 的数字,该数字包含等于 digits的一些小数位数。

例外

digits 小于 0 或大于 15。

注解

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

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

重要

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

如果参数的值为value,则该方法返回 Double.NaNDouble.NaN 如果 valueDouble.PositiveInfinityDouble.NegativeInfinity,则该方法分别返回 Double.PositiveInfinityDouble.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
open System

printfn $"{Math.Round(3.44, 1)}" //Returns 3.4.
printfn $"{Math.Round(3.45, 1)}" //Returns 3.4.
printfn $"{Math.Round(3.46, 1)}" //Returns 3.5.

printfn $"{Math.Round(4.34, 1)}" // Returns 4.3
printfn $"{Math.Round(4.35, 1)}" // Returns 4.4
printfn $"{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。 之所以发生这种情况,是因为该方法在内部乘 value 以 10,在这种情况下,乘法运算会丢失精度。

using System;

public class Example
{
   public static void Main()
   {
      double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 };
      foreach (double value in values)
         Console.WriteLine("{0} --> {1}", value, Math.Round(value, 2));
   }
}
// The example displays the following output:
//       2.125 --> 2.12
//       2.135 --> 2.13
//       2.145 --> 2.14
//       3.125 --> 3.12
//       3.135 --> 3.14
//       3.145 --> 3.14
open System

let values = [| 2.125; 2.135; 2.145; 3.125; 3.135; 3.145 |]
for value in values do
    printfn $"{value} --> {Math.Round(value, 2)}"
// The example displays the following output:
//       2.125 --> 2.12
//       2.135 --> 2.13
//       2.145 --> 2.14
//       3.125 --> 3.12
//       3.135 --> 3.14
//       3.145 --> 3.14
Module Example
   Public Sub Main()
      Dim values() As Double = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 }
      For Each value As Double In values
         Console.WriteLine("{0} --> {1}", value, Math.Round(value, 2))
      Next
   End Sub
End Module
' The example displays the following output:
'       2.125 --> 2.12
'       2.135 --> 2.13
'       2.145 --> 2.14
'       3.125 --> 3.12
'       3.135 --> 3.14
'       3.145 --> 3.14

另请参阅

适用于

Round(Decimal, Int32)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

将十进制值舍入为指定的小数位数,并将中点值舍入为最接近的偶数。

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

返回值中的小数位数。

返回

最接近 d 的数字,该数字包含等于 decimals的一些小数位数。

例外

decimals 小于 0 或大于 28。

结果不在一个 Decimal范围之外。

注解

参数的值 decimals 可以介于 0 到 28 范围内。

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

重要

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

示例

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

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
open System

printfn 
    $"""{Math.Round(3.44m, 1)}
{Math.Round(3.45m, 1)}
{Math.Round(3.46m, 1)}

{Math.Round(4.34m, 1)}
{Math.Round(4.35m, 1)}
{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)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

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

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

要舍入的双精度浮点数。

返回

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

注解

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

重要

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

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

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

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

示例

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

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
open System

printfn "Classic Math.Round in F#"
printfn $"{Math.Round(4.4)}" // 4
printfn $"{Math.Round(4.5)}" // 4
printfn $"{Math.Round(4.6)}" // 5
printfn $"{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。

using System;

public class Example
{
   public static void Main()
   {
      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} --> {1}", value, Math.Round(value));
      return value + .1;
   }
}
// The example displays the following output:
//       11.1 --> 11
//       11.2 --> 11
//       11.3 --> 11
//       11.4 --> 11
//       11.5 --> 11
//       11.6 --> 12
//
//       11.5 --> 12
open System

let roundValueAndAdd (value: float) =
    printfn $"{value} --> {Math.Round value}"
    value + 0.1

let mutable value = 11.1

for _ = 0 to 5 do
    value <- roundValueAndAdd value

printfn ""

value <- 11.5
roundValueAndAdd value
|> ignore

// The example displays the following output:
//       11.1 --> 11
//       11.2 --> 11
//       11.3 --> 11
//       11.4 --> 11
//       11.5 --> 11
//       11.6 --> 12
//
//       11.5 --> 12
Module Example
   Public Sub Main()
      Dim value As Double = 11.1
      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} --> {1}", value, Math.Round(value))
      Return value + .1
   End Function   
End Module
' The example displays the following output:
'       11.1 --> 11
'       11.2 --> 11
'       11.3 --> 11
'       11.4 --> 11
'       11.5 --> 11
'       11.6 --> 12
'       
'       11.5 --> 12

另请参阅

适用于

Round(Decimal)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

将十进制值舍入到最接近的整数值,并将中点值舍入为最接近的偶数。

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

要舍入的十进制数。

返回

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

例外

结果不在一个 Decimal范围之外。

示例

以下示例演示了该方法 Round(Decimal)Decimal 4.5 的值为 4 而不是 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
open System

for value in 4.2m .. 0.1m .. 4.8m do
    printfn $"{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 有关使用中点值的舍入数字的信息,请参阅 Midpoint 值和舍入约定

重要

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

另请参阅

适用于

Round(Decimal, MidpointRounding)

Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs
Source:
Math.cs

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

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

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

返回

舍入为的 d 整数。 此方法返回一个 Decimal 而不是整型类型。

例外

mode 不是有效值 MidpointRounding

结果不在一个 Decimal范围之外。

注解

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

重要

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

示例

以下示例显示方法返回 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
printfn $"""{"Value",-10} {"Default",-10} {"ToEven",-10} {"AwayFromZero",-15} {"ToZero",-15}"""
for value in 12m .. 0.1m .. 13m do
    printfn "%-10O %-10O %-10O %-15O %-15O" 
        value
        (Math.Round value)
        (Math.Round(value, MidpointRounding.ToEven))
        (Math.Round(value, MidpointRounding.AwayFromZero))
        (Math.Round(value, MidpointRounding.ToZero))

// 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

另请参阅

适用于