Подтвердить что ты не робот

.Net Rounding Issue

У меня проблема округления внутри .Net.

Я округляю 3-значное число до двух цифр, и это вызывает некоторые проблемы с одним номером.

Если я попытаюсь округлить 34.425 до двух знаков после запятой, он должен округлить его до 34.43. Я использую параметр roundawayfromzero, и он работал для каждого числа в программе, за исключением этого.

Код Math.Round(34.425, 2, MidpointRounding.AwayFromZero) должен равняться 34.43, однако он равен 34.42.

Если я попробую это с любым другим номером, он отлично работает.

Math.Round(34.435, 2, MidpointRounding.AwayFromZero) = 34.44

Math.Round(34.225, 2, MidpointRounding.AwayFromZero) = 34.23

Math.Round(34.465, 2, MidpointRounding.AwayFromZero) = 34.47

Я просто хотел проверить, не сталкивался ли кто-нибудь с этой проблемой раньше?

Сейчас я исправил эту проблему, преобразовывая число в десятичное. Я изменил код на это, и теперь он отлично работает:

Math.Round(CDec(34.425), 2, MidpointRounding.AwayFromZero) = 34.43

Я просто ищу причину, почему мой старый код не работал.

Спасибо!

Обновлен код до правильного AwayFromZero

4b9b3361

Ответ 1

Плавающая точка никогда не бывает точной, 34.425 может иметь внутреннюю репрезентацию 34.4249999999999.. которая будет округлена до 34.42.

Если вам нужно точное представление чисел, используйте тип decimal.

Ответ 2

Немного смущен, действительно ли вы используете MidpointRounding.ToEven или MidpointRounding.AwayFromZero. Если вы используете ToEven, как показывает первый фрагмент, это ожидаемое поведение.

Ответ 3

Ваши предположения и результаты неверны:

Math.Round(34.225, 2, MidpointRounding.ToEven) == 34.22
Math.Round(34.465, 2, MidpointRounding.ToEven) == 34.46

и

Math.Round(34.425, 2, MidpointRounding.ToEven) == 34.42

То, как это работает, и то, что я получаю на своей коробке. Округление означает даже это, округляя вверх или вниз, чтобы перейти к следующему четному числу в десятичной точке.

Ответ 4

Код Math.Round(34.425, 2, MidpointRounding.ToEven) должен равняться 34.43, однако он равен 34.42.

Почему? ToEven должен сделать это 34.42, так как 42 четный. Поведение правильное.

Ответ 5

Я не использую vb.net, поэтому мои рассуждения могут быть неправильными, но на основе названий ваших параметров MidpointRounding.ToEven, я ожидал бы, что 34.425 будет округлено до 34.42; но я также ожидал, что 34.225 будет округлено до 34.22 и 34.465 до 34.46. Округление чисел, которое заканчивается на 5, как в ваших примерах, является условным. Самое обычное соглашение округлено до четного числа, которое я вывел на ваш .ToEven параметр будет принимать.

Кроме того, я подозреваю, что вы сталкиваетесь с проблемой округления двоичных/десятичных чисел. Проверка двоичного представления 34.425 выводится как 10010.011011....... Когда вы берете память компьютера и представление десятичного числа (байт, слово, двойное слово, четырехзначное слово и отрицательное/положительное дополнение), это может привести к в котором вы не округлили число, о котором вы считали.

Чтобы получить нужные результаты, вы должны, вероятно, добавить 0.00001 к любой цифре, заканчивающейся до 5, перед округлением.