Math.Round для десятичной дроби

Я запускаю этот код:

decimal d = 1.45M;

Console.WriteLine((System.Math.Round(d,0,MidpointRounding.AwayFromZero).ToString()));

Здесь я ожидаю, что на выходе будет 2, потому что 1,45 при округлении до 1-го десятичного знака будет 1,5, что при следующем округлении до 0 десятичных знаков должно быть 2.

Однако я получаю ответ как 1.

Верно ли мое предположение? Если да, то является ли это ошибкой с Math.Round?


person Jeevan    schedule 06.09.2010    source источник


Ответы (3)


Нет, это не ошибка. Ваша логика говорит об округлении дважды, но у вас есть только один вызов Round. 1,45 меньше среднего значения между 1 и 2 (1,5), поэтому оно округляется до 1.

Если вы хотите, чтобы код следовал вашей логике, вы можете сделать это:

using System;

class Test
{
    static void Main()
    {
        decimal d = 1.45m;
        d = Math.Round(d, 1, MidpointRounding.AwayFromZero); // 1.5
        d = Math.Round(d, 0, MidpointRounding.AwayFromZero); // 2

        Console.WriteLine(d);
    }
}

Если вы не укажете, что вам нужны две фазы округления (как указано выше), .NET просто выполнит одну.

person Jon Skeet    schedule 06.09.2010
comment
d = Math.Round(d, 0, MidpointRounding.AwayFromZero); вывод будет 1 а не 2. - person PrateekSaluja; 06.09.2010
comment
@prateeksaluja20: Я запустил его. Результатом было 2. Имейте в виду, что d составляет 1,5 м, когда выполняется второй вызов Math.Round... обратите внимание на присвоение d результатам первого вызова. - person Jon Skeet; 06.09.2010
comment
Да, я проверил, присвоил ли я значение, поэтому вывод будет таким. - person PrateekSaluja; 06.09.2010
comment
Спасибо, Джон. Я просто подумал, что .net начнет округлять значение с самой правой цифры и показывать только до указанного числа десятичных знаков. - person Jeevan; 06.09.2010

Вы не можете округлить одну цифру за другой! Вот вы говорите:

1.45 rounded to 1 decimal place:1.5
1.5 rounded to 0 decimal place:2

Это неправильно, здесь 1,45 округляется до 0 знаков, нужно проверять только .4.

person Cheng Chen    schedule 06.09.2010

Ваше понимание неверно.

Вы указали десятичное значение 0, поэтому указанное значение будет округлено до целого числа.

Из MSDN «Если значение первой цифры в d справа от десятичной позиции, представленной параметром десятичных знаков, равно 5, цифра в десятичной позиции округляется в большую сторону, если она нечетная, или остается одна, если она четная»

Поскольку первое значение справа от десятичной точки равно 4, а не пяти, возвращаемое значение равно 1.

Если бы десятичное значение было 1,55, то ответ был бы 2.

Если бы десятичное значение было 2,55, то ответ тоже был бы 2!

Поскольку вы указываете поведение округления средней точки, это будет изменено, но вы просите, чтобы округление работало с десятичными знаками = 0, оно будет проверять только первую цифру после десятичной точки.

На самом деле, если вы указали десятичные знаки = 1, как в

Math.Round(1.45,1)

Тогда ваш ответ будет 1,4, так как он проверяет вторую цифру после запятой для округления первой.

person ChrisBD    schedule 06.09.2010