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

Что не так с 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 без баловаться с десятичной частью? (как естественная логика математики)

4b9b3361

Ответ 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")