Есть ли встроенная функция, которая может крутиться так:
10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20
Есть ли встроенная функция, которая может крутиться так:
10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20
Я не знаю стандартной функции в Python, но это работает для меня:
def myround(x, base=5):
return int(base * round(float(x)/base))
Легко понять, почему это работает. Вы хотите убедиться, что ваш номер, деленный на 5, является целым числом, правильно округленным. Итак, сначала сделаем точно, что (round(float(x)/5)
), а затем, поскольку мы разделили на 5, умножим также на 5. Окончательное преобразование в int
происходит потому, что round()
возвращает значение с плавающей запятой в Python.
Я сделал функцию более общей, указав ей параметр base
, по умолчанию 5.
Для округления до нецелых значений, например 0,05:
def myround(x, prec=2, base=.05):
return round(base * round(float(x)/base),prec)
Я нашел это полезным, так как я мог просто выполнить поиск и заменить в своем коде, чтобы изменить "round" ( "to" myround (", не изменяя значения параметров.
Это просто вопрос масштабирования
>>> a=[10,11,12,13,14,15,16,17,18,19,20]
>>> for b in a:
... int(round(b/5.0)*5.0)
...
10
10
10
15
15
15
15
15
20
20
20
Удаление "остального" будет работать:
rounded = int(val) - int(val) % 5
Если значение равно целому числу:
rounded = val - val % 5
Как функция:
def roundint(value, base=5):
return int(value) - int(value) % int(base)
round (x [, n]): значения округляются до ближайшего кратного 10 до мощности минус n. Поэтому, если n отрицательно...
def round5(x):
return int(round(x*2, -1)) / 2
Так как 10 = 5 * 2, вы можете использовать целочисленное деление и умножение с 2, а не с плавающим делением и умножением с 5.0. Не то, что это имеет большое значение, если вам не нравится смещение бит
def round5(x):
return int(round(x << 1, -1)) >> 1
Извините, я хотел прокомментировать ответ Алока Сингая, но это не позволит мне из-за отсутствия репутации =/
В любом случае, мы можем обобщить еще один шаг и пойти:
def myround(x, base=5):
return base * round(float(x) / base)
Это позволяет использовать нецелые базы, такие как .25
или любую другую дробную базу.
Измененная версия divround: -)
def divround(value, step, barrage):
result, rest = divmod(value, step)
return result*step if rest < barrage else (result+1)*step
def round_to_next5(n):
return n + (5 - n) % 5
Я понимаю, что опаздываю на вечеринку, но похоже, что это решение не упоминалось:
>>> from __future__ import division # This is only needed on Python 2
>>> def round_to_nearest(n, m):
r = n % m
return n + m - r if r + r >= m else n - r
...
Он не использует умножение и не будет конвертировать из/в поплавки.
Округление до ближайшего кратного 10:
>>> for n in range(-21, 30, 3): print('{:3d} => {:3d}'.format(n, round_to_nearest(n, 10)))
-21 => -20
-18 => -20
-15 => -10
-12 => -10
-9 => -10
-6 => -10
-3 => 0
0 => 0
3 => 0
6 => 10
9 => 10
12 => 10
15 => 20
18 => 20
21 => 20
24 => 20
27 => 30
Как вы можете видеть, он работает как для отрицательных, так и для положительных чисел. Связи (например, -15 и 15) всегда будут округлены вверх.
Аналогичный пример, который не округляет ближайший кратный 5, демонстрируя, что он также ведет себя как ожидалось для другой "базы":
>>> for n in range(-21, 30, 3): print('{:3d} => {:3d}'.format(n, round_to_nearest(n, 5)))
-21 => -20
-18 => -20
-15 => -15
-12 => -10
-9 => -10
-6 => -5
-3 => -5
0 => 0
3 => 5
6 => 5
9 => 10
12 => 10
15 => 15
18 => 20
21 => 20
24 => 25
27 => 25
Если кому-то нужно "финансовое округление" (0,5 раунда всегда вверх):
def myround(x, base=5):
roundcontext = decimal.Context(rounding=decimal.ROUND_HALF_UP)
decimal.setcontext(roundcontext)
return int(base *float(decimal.Decimal(x/base).quantize(decimal.Decimal('0'))))
В соответствии с документацией другие варианты округления:
ROUND_CEILING (к бесконечности),
ROUND_DOWN (к нулю),
ROUND_FLOOR (в сторону -Infinity),
ROUND_HALF_DOWN (ближайший с привязкой к нулю),
ROUND_HALF_EVEN (ближе к ближайшему с ближайшим четным целым),
ROUND_HALF_UP (до ближайшего с уклонениями от нуля), или
ROUND_UP (вдали от нуля).
ROUND_05UP (вдали от нуля, если последняя цифра после округления к нулю равна 0 или 5, в противном случае - к нулю)
По умолчанию Python использует ROUND_HALF_EVEN, поскольку он имеет некоторые статистические преимущества (округленные результаты не предвзяты).
Как насчет этого:
def divround(value, step):
return divmod(value, step)[0] * step
** следующий кратный 5 **
считать 51 необходимо преобразовать в 55
code here
mark=51;
r=100-mark;
a=r%5;
new_mark=mark+a;
Вы можете "обмануть" int()
округлить, а не округлять, добавив 0.5
к
номер, который вы переходите на int()
.