Is there a built-in function that can round like the following?
10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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))
Method 2
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.
Method 3
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
Method 4
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)
Method 5
def round_to_next5(n):
return n + (5 - n) % 5
Method 6
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
Method 7
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.
Method 8
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
Method 9
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
Method 10
Modified version of divround 🙂
def divround(value, step, barrage):
result, rest = divmod(value, step)
return result*step if rest < barrage else (result+1)*step
Method 11
For integers and with Python 3:
def divround_down(value, step):
return value//step*step
def divround_up(value, step):
return (value+step-1)//step*step
Producing:
>>> [divround_down(x,5) for x in range(20)] [0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15] >>> [divround_up(x,5) for x in range(20)] [0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 20, 20, 20, 20]
Method 12
In case someone needs “financial rounding” (0.5 rounds always up):
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'))))
As per documentation other rounding options are:
ROUND_CEILING (towards Infinity),
ROUND_DOWN (towards zero),
ROUND_FLOOR (towards -Infinity),
ROUND_HALF_DOWN (to nearest with ties going towards zero),
ROUND_HALF_EVEN (to nearest with ties going to nearest even integer),
ROUND_HALF_UP (to nearest with ties going away from zero), or
ROUND_UP (away from zero).
ROUND_05UP (away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise towards zero)
By default Python uses ROUND_HALF_EVEN as it has some statistical advantages (the rounded results are not biased).
Method 13
Next multiple of 5
Consider 51 needs to be converted to 55:
code here mark = 51; r = 100 - mark; a = r%5; new_mark = mark + a;
Method 14
Another way to do this (without explicit multiplication or division operators):
def rnd(x, b=5):
return round(x + min(-(x % b), b - (x % b), key=abs))
Method 15
No one actually wrote this yet I guess but you can do:
round(12, -1) --> 10 round(18, -1) --> 20
Method 16
What about this:
def divround(value, step):
return divmod(value, step)[0] * step
Method 17
Here is my C code. If I understand it correctly, it should supposed to be something like this;
#include <stdio.h>
int main(){
int number;
printf("Enter number: n");
scanf("%d" , &number);
if(number%5 == 0)
printf("It is multiple of 5n");
else{
while(number%5 != 0)
number++;
printf("%dn",number);
}
}
and this also rounds to nearest multiple of 5 instead of just rounding up;
#include <stdio.h>
int main(){
int number;
printf("Enter number: n");
scanf("%d" , &number);
if(number%5 == 0)
printf("It is multiple of 5n");
else{
while(number%5 != 0)
if (number%5 < 3)
number--;
else
number++;
printf("nearest multiple of 5 is: %dn",number);
}
}
Method 18
I needed to round down to the preceding 5.
Example 16 rounds down to 15 or 19 rounds down to 15
Here’s the code used
def myround(x,segment):
preRound = x / segment
roundNum = int(preRound)
segVal = segment * roundNum
return segVal
Method 19
An addition to accepted answer, to specify rounding up or down to nearest 5-or-whatever
import math
def my_round(x, base, down = True):
return base * math.floor(x/base) + (not down) * base
Method 20
You can “trick” int() into rounding off instead of rounding down by adding 0.5 to the
number you pass to int().
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0