#.net #vb.net #math #rounding
#.net #vb.net #математика #округление
Вопрос:
Я должен использовать метод round, который следует этому поведению:
7.00 -> round -> 7
7.50 -> round -> 7
7.51 -> round -> 8
Я пытался использовать Math.Round, но это работает немного по-другому.
Dim val As Decimal = 7.5
Dim a As Decimal = Math.Round(val, 0) ' -> 8
Dim b As Decimal = Math.Round(val, 0, MidpointRounding.AwayFromZero) ' -> 8
Dim c As Decimal = Math.Round(val, 0, MidpointRounding.ToEven) ' -> 8
Как я могу реализовать свою логику округления?
Комментарии:
1. Итак, вы хотите, чтобы все варианты X.5 были равны X? Стандартом для C # является то, что если значение равно X.5, оно округляется до ближайшего четного числа. Таким образом, и 7.5, и 8.5 будут округлены до 8.
2. Кстати, ваш код написан на VB, а не на C#
3. почему вы пометили этот вопрос как C # (в обоих тегах и названии), но опубликовали код на VB?
4. Простой ответ: способ, которым вы хотите выполнить округление, неверен. Это не соответствует никакому стандартному соглашению и поэтому довольно бесполезно. Платформа .NET Framework предоставляет вам две общепринятые формы:
AwayFromZero
(также известную как то, чему вы учились в школе) иToEvent
(также известную как округление «Банкира»). Подробности в документации .5. Извините, я испортил проект code… Я разработчик на C # и VB … и иногда это сводит меня с ума 🙂 Однако я знаю, что это не стандартное поведение, но есть особый случай, в котором это необходимо сделать.
Ответ №1:
Вы могли бы вычесть 0.01
из общего числа, а затем вызвать Math.round(..)
.
double d = 7.5;
double result = Math.Round(d - 0.01);
Если число отрицательное, вам нужно будет сделать следующее, чтобы получить тот же результат:
double d = -7.5;
if (d < 0)
{
double tmp = Math.Abs(d) - 0.01;
double result = -Math.Round(tmp);
}
Вот рабочий пример.
Однако обратите внимание, что это поведение, вероятно, не то, чего вы хотите, как отметили несколько других.
Если вы читали комментарии к этому ответу, @alex zhevzhik также отметил, что это решение завершится неудачей, если входные данные будут содержать более 2 десятичных знаков.
Комментарии:
1. И что делает ваше решение, когда число отрицательное?
2. Как насчет округления 7.50000009? Ваше решение округлит его до 7.0, между тем все указывает на то, что правильный ответ равен 8.0
3. @alex zhevzhik: Вы правы, но пример, приведенный LukePet, не предполагает, что он столкнется с таким числом.
Ответ №2:
Midpoint не удалось обеспечить соответствующую функциональность. Взгляните на первую и третью строки в таблице в примечаниях. Если вы измените значение val на 6.5, вы получите ожидаемое поведение, но не с 7.5.
Вы должны написать свою собственную реализацию такого округления.
Реализация Джаведа Акрама хороша, но она работает совершенно неправильно с отрицательными числами. Поскольку вы не предоставили подробностей округления отрицательных чисел, я полагаю, что стандартное округление подходит. Кроме того, вы должны учитывать «специальные» двойные значения:
static class Helper
{
public static double Round(double val)
{
if (Double.IsNaN(val) || Double.IsNegativeInfinity(val) || Double.IsPositiveInfinity(val))
{
return val;
}
var decimalPart = Math.Truncate(val);
if (val >= 0)
{
if (val - decimalPart <= 0.5)
{
return Math.Floor(val);
}
else
{
return Math.Ceiling(val);
}
}
else
{
return Math.Round(val, 0);
}
}
}
Ответ №3:
Ну, я не знаю, существует ли математика.Метод Round, который делает то, что вы хотите, но я думаю, вам нужно будет написать свой собственный. Потому что обычно 7.5 округляется до 8, если только я не забыл все, чему научился в средней школе.
Ответ №4:
Dim i As Decimal
Dim j As Integer
Dim k As Decimal
i = 7.51
k = i - Math.Truncate(i) 'decimal part of number
If (k <= 0.5) Then
j = Math.Floor(i)
Else
j = Math.Ceiling(i)
End If