I want to round up numbers in Python to a specified decimal.
For example, if I choose
(2.1, 0.2) --> I want to get 2.2
(2.2, 0.2) --> I want to get 2.2
(3.6, 0.5) --> I want to get 4.0
(3.5, 0.5) --> I want to get 3.5
I want to round up numbers in Python to a specified decimal.
For example, if I choose
(2.1, 0.2) --> I want to get 2.2
(2.2, 0.2) --> I want to get 2.2
(3.6, 0.5) --> I want to get 4.0
(3.5, 0.5) --> I want to get 3.5
probably not the most efficient, but working with numpy
I am assuming that you are working with not too much decimals
import numpy as np
def rounder(num, round_):
int_p = np.floor(num)
float_p = num - int_p
print(float_p) # this print is meant to show the floating point problem
diff = float_p - round_
if diff <= 0 or -0.00001 <diff< 0.00001:
return int_p + round_
else:
return np.ceil(num)
list_ = [(2.1, 0.2), (2.2, 0.2), (3.6, 0.5), (3.5, 0.5)]
for num, round_ in list_:
print("({}, {})".format(num, round_), rounder(num, round_))
# (2.1, 0.2) 2.2
# (2.2, 0.2) 2.2
# (3.6, 0.5) 4.0
# (3.5, 0.5) 3.5
unfortunately there are problems with the representation of the floating point that is not so precise. That's the reason why I wrote another condition in the if else -0.00001 <diff< 0.00001
that means, if the difference is not so high (near zero) than it is basically zero
New algorithm as requested from op
import numpy as np
def rounder(num, round_):
int_p = np.floor(num)
new_value = int_p
while new_value < num:
new_value = round(new_value + round_, 4)
return new_value
list_ = [(2.1, 0.2), (2.2, 0.2), (3.6, 0.5), (3.5, 0.5), (0.178, 0.1)]
for num, round_ in list_:
print("({}, {})".format(num, round_), rounder(num, round_))
# (2.1, 0.2) 2.2
# (2.2, 0.2) 2.2
# (3.6, 0.5) 4.0
# (3.5, 0.5) 3.5
# (0.178, 0.1) 0.2
What I wanted was:
def rounder(num, round_):
val = num // round_
if val*round_ == num:
return num
else:
return val*round_ + round_
list_ = [(9.3, 0.4), (2.2, 0.2), (3.6, 0.5), (3.5, 0.5), (0.178, 0.1)]
for num, round_ in list_:
print("({}, {})".format(num, round_), rounder(num, round_))
Assume that rounder(x, y)
is some multiple of y that is closest to x. If there are two such multiples, choose the one that has a higher absolute value.
Python has an issue of rounding halves:
>>> round(10.5)
10
>>> np.round(10.5)
10.0
Borrowing from this simple fix, I'll extend it for OP's question
import math
def rounder(x, y):
r = x/y
if (r - int(r) >= 0.5):
return y * math.ceil(r)
else:
return y * math.floor(r)
Sample run:
>>> rounder(2.1, 0.2)
2.2
>>> rounder(2.2, 0.2)
2.2
>>> rounder(3.6, 0.5)
3.5
>>> rounder(3.5, 0.5)
3.5
This is designed to call it multiple times on items, usually in a process of some iterations.
It's also possible to rewrite it in order to work in vectorised way:
def rounder(x, y):
r = x/y
np.where(r-r//1 >= 0.5, y * np.ceil(r), y * np.floor(r))
>>> rounder(np.array([2.1,2.2,3.6,3.5]), np.array([0.2, 0.2, 0.5, 0.5]))
array([2.2, 2.2, 3.5, 3.5])