Что не так с Math.Round() в VB.Net?
Я столкнулся со странным случаем в функции Math.Round в VB.Net
Math.Round((32.625), 2)
Результат: 32,62
Math.Round((32.635), 2)
Результат: 32,64
Мне нужно 32.63, но в этих случаях функция работает в другой логике.
Я могу получить десятичную часть и сделать то, что я хочу, что-то сделать с ней. Но не слишком ли это странно, кто-то округляется до более высокого, кто-то округляется до более низкого?
Так как я могу получить 32.63 от 32.625 без баловаться с десятичной частью? (как естественная логика математики)
Ответы
Ответ 1
Math.Round
использует округление банкиров по умолчанию. Вы можете изменить это, указав другую опцию MidPointRounding
. Из MSDN:
Округление с нуля
Средние значения округляются до следующего числа от нуля. Для например, 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.
Округление до ближайшей является стандартной формой округления, используемой в финансовых и статистические операции. Он соответствует стандарту IEEE 754, раздел 4. При использовании в нескольких операциях округления уменьшает ошибку округления, вызванную постоянным округлением средних значений в одно направление. В некоторых случаях эта ошибка округления может быть существенным.
Итак, вы хотите:
Math.Round(32.625, 2, MidpointRounding.AwayFromZero)
Math.Round(32.635, 2, MidpointRounding.AwayFromZero)
Как уже упоминалось, если точность важна, вы должны использовать переменные Decimal
, а не типы с плавающей запятой. Например:
Math.Round(32.625D, 2, MidpointRounding.AwayFromZero)
Math.Round(32.635D, 2, MidpointRounding.AwayFromZero)
Ответ 2
Попробуйте это (из памяти):
Math.Round((32.635), 2, MidPointRounding.AwayFromZero)
Ответ 3
Попробуйте это.
Dim d As Decimal = 3.625
Dim r As Decimal = Math.Ceiling(d * 100D) / 100D
MsgBox(r)
Это должно делать то, что вы хотите.
Ответ 4
У вас есть функция быстрого доступа, которую вы можете добавить, чтобы упростить свою жизнь и сделать ее так, чтобы вам не приходилось вводить так много всего времени.
Private Function roundd(dec As Decimal)
Dim d As Decimal = dec
Dim r As Decimal = Math.Ceiling(d * 100D) / 100D
Return r
End Function
Добавьте это в свое приложение, затем используйте функцию
roundd(3.624)
или что вам нужно.
чтобы отобразить результат - пример
msgbox(roundd(3.625))
Появится сообщение с номером 3.63
Textbox1.text = roundd(3.625)
это установит textbox1.text - 3.63 и т.д. и т.д.
Поэтому, если вам нужно округлить больше, чем один номер, это будет не так утомительно, и вы можете сохранить много набрав.
Надеюсь, это поможет.
Ответ 5
Вы не можете использовать поплавки, которые относятся к числу таких чисел, как 32.625, как в VB.Net. (Существует также вопрос об округлении Banker как упоминание @StevenDoggart - вам, вероятно, придется иметь дело с обоими проблемами.)
Проблема заключается в том, что сохраненное число не является тем, что введено, потому что эти числа не имеют фиксированного двоичного представления, например. 32.625 хранится как 32.62499997 и 32.635 как 32.63500001.
Единственный способ быть точным - хранить числа как тип Decimal
DIM num as Decimal
num = ToDecimal("32.625")