I may be missing something essential, but I can't figure out a way to 'properly' round floats/Decimals in Python (2.7), at least to three decimal places. By 'properly' I mean that 1.2225 should round to 1.223, and 1.2224 should round to 1.222.
I know round
won't work for floats in Python, by design, but I can't seem to get Decimal
to behave as expected, nor the ceil
function. Looking for built-in functionality rather than custom function workarounds preferably, but open to both.
>>> x = 1.2225 # expected: 1.223
>>> round(x, 3)
1.222 # incorrect
>>> from math import ceil
>>> ceil(x * 1000.0) / 1000.0
1.223 # correct
>>> y = 1.2224 # expected: 1.222
>>> ceil(y * 1000.0) / 1000.0
1.223 # incorrect
>>> from decimal import Decimal, ROUND_UP, ROUND_HALF_UP
>>> x = Decimal(1.2225)
>>> x.quantize(Decimal('0.001'), ROUND_UP)
Decimal('1.223') # correct
>>> y = Decimal(1.2224)
>>> y.quantize(Decimal('0.001'), ROUND_UP)
Decimal('1.223') # incorrect
>>> y.quantize(Decimal('0.001'), ROUND_HALF_UP)
Decimal('1.222') # correct
>>> x.quantize(Decimal('0.001'), ROUND_HALF_UP)
Decimal('1.222') # incorrect
Is there a way to get the desired result?
The problem is that Decimal(1.2225)
is not what you expect it to be:
>>> Decimal(1.2225)
Decimal('1.2224999999999999200639422269887290894985198974609375')
You are using a float to the create the decimal, but that float is already too imprecise for your use case. As you can see, it’s actually a 1.222499
so it is smaller than 1.2225
and as such would correctly round down.
In order to fix that, you need to create decimals with correct precision, by passing them as strings. Then everything works as expected:
>>> x = Decimal('1.2225')
>>> x.quantize(Decimal('0.001'), ROUND_HALF_UP)
Decimal('1.223')
>>> y = Decimal('1.2224')
>>> y.quantize(Decimal('0.001'), ROUND_HALF_UP)
Decimal('1.222')
Here are three solution in this link, I hope this would help you exactly what you want to do. https://gist.github.com/jackiekazil/6201722
from decimal import Decimal
# First we take a float and convert it to a decimal
x = Decimal(16.0/7)
# Then we round it to 2 places
output = round(x,2)
# Output to screen
print output
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With