# 在 Python 中舍入到 5（或其他数字）

``````10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20
`````` Round to 5 (or other number) in Python

I don't know of a standard function in Python, but this works for me:

### Python 3

``````def myround(x, base=5):
return base * round(x/base)
``````

It is easy to see why the above works. You want to make sure that your number divided by 5 is an integer, correctly rounded. So, we first do exactly that (`round(x/5)`), and then since we divided by 5, we multiply by 5 as well.

I made the function more generic by giving it a `base` parameter, defaulting to 5.

### Python 2

In Python 2, `float(x)` would be needed to ensure that `/` does floating-point division, and a final conversion to `int` is needed because `round()` returns a floating-point value in Python 2.

``````def myround(x, base=5):
return int(base * round(float(x)/base))
``````

### 答案: For rounding to non-integer values, such as 0.05:

``````def myround(x, prec=2, base=.05):
return round(base * round(float(x)/base),prec)
``````

I found this useful since I could just do a search and replace in my code to change "round(" to "myround(", without having to change the parameter values. It's just a matter of scaling

``````>>> 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
`````` Removing the 'rest' would work:

``````rounded = int(val) - int(val) % 5
``````

If the value is aready an integer:

``````rounded = val - val % 5
``````

As a function:

``````def roundint(value, base=5):
return int(value) - int(value) % int(base)
`````` ``````def round_to_next5(n):
return n + (5 - n) % 5
`````` round(x[, n]): values are rounded to the closest multiple of 10 to the power minus n. So if n is negative...

``````def round5(x):
return int(round(x*2, -1)) / 2
``````

Since 10 = 5 * 2, you can use integer division and multiplication with 2, rather than float division and multiplication with 5.0. Not that that matters much, unless you like bit shifting

``````def round5(x):
return int(round(x << 1, -1)) >> 1
`````` Sorry, I wanted to comment on Alok Singhai's answer, but it won't let me due to a lack of reputation =/

Anyway, we can generalize one more step and go:

``````def myround(x, base=5):
return base * round(float(x) / base)
``````

This allows us to use non-integer bases, like `.25` or any other fractional base. Use:

``````>>> def round_to_nearest(n, m):
r = n % m
return n + m - r if r + r >= m else n - r
``````

It does not use multiplication and will not convert from/to floats.

Rounding to the nearest multiple of 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
``````

As you can see, it works for both negative and positive numbers. Ties (e.g. -15 and 15) will always be rounded upwards.

A similar example that rounds to the nearest multiple of 5, demonstrating that it also behaves as expected for a different "base":

``````>>> 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
`````` ``````def round_up_to_base(x, base=10):
return x + (base - x) % base

def round_down_to_base(x, base=10):
return x - (x % base)
``````

which gives

for `base=5`:

``````>>> [i for i in range(20)]
[0, 1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
``````
``````>>> [round_down_to_base(x=i, base=5) for i in range(20)]
[0, 0,  0,  0,  0,  5,  5,  5,  5,  5,  10, 10, 10, 10, 10, 15, 15, 15, 15, 15]

>>> [round_up_to_base(x=i, base=5) for i in range(20)]
[0, 5,  5,  5,  5,  5,  10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20, 20, 20, 20]
``````

for `base=10`:

``````>>> [i for i in range(20)]
[0, 1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
``````
``````>>> [round_down_to_base(x=i, base=10) for i in range(20)]
[0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

>>> [round_up_to_base(x=i, base=10) for i in range(20)]
[0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20]
``````

tested in Python 3.7.9 Modified version of divround :-)

``````def divround(value, step, barrage):
result, rest = divmod(value, step)
return result*step if rest < barrage else (result+1)*step
``````