Reputation: 823
I want to round number in python but it keep giving me the inaccurate result for example I want to round 99.999999946 into 99.99, or 56.3633333 into 56.36 this is what I've tried:
int(99.999999946*100)/100 #result = 99
int(99.999999946*100)/100.0 #result = 99.989999999999995
round(99.999999946, 2) #result = 100.0
thanks before
Upvotes: 2
Views: 2876
Reputation: 967
This allows you to round to the desired number of decimal places.
def round_decimal(dec, places=2):
return int((dec * 10**places) + 0.5) / 10.**places
Upvotes: 0
Reputation: 70592
Until you get comfortable with limitations of binary floating point, you'll probably be much happier with the decimal
module, which implements a rich decimal floating-point model. Among other things, it allows fine control over rounding modes:
>>> import decimal
>>> d = decimal.Decimal("99.999999946")
>>> print d
99.999999946
>>> chopped = d.quantize(decimal.Decimal(".01"), decimal.ROUND_DOWN)
>>> print chopped
99.99
Here's a function that will chop to any digit position you like, and returning a float too (which is, in general, inexact!):
def chop_to_n_decimals(x, n):
# This "rounds towards 0". The decimal module
# offers many other rounding modes - see the docs.
import decimal
d = decimal.Decimal(repr(x))
targetdigit = decimal.Decimal("1e%d" % -n)
chopped = d.quantize(targetdigit, decimal.ROUND_DOWN)
return float(chopped)
For example,
for x in 5555.5555, -5555.5555:
for n in range(-3, 4):
print x, n, "->", chop_to_n_decimals(x, n)
displays:
5555.5555 -3 -> 5000.0
5555.5555 -2 -> 5500.0
5555.5555 -1 -> 5550.0
5555.5555 0 -> 5555.0
5555.5555 1 -> 5555.5
5555.5555 2 -> 5555.55
5555.5555 3 -> 5555.555
-5555.5555 -3 -> -5000.0
-5555.5555 -2 -> -5500.0
-5555.5555 -1 -> -5550.0
-5555.5555 0 -> -5555.0
-5555.5555 1 -> -5555.5
-5555.5555 2 -> -5555.55
-5555.5555 3 -> -5555.555
Upvotes: 3
Reputation: 287835
All the results are correct. int
rounds down, whereas round
rounds to the nearest number (i.e. digits 0-4 get rounded down, 5-9 up for positive numbers). In Python 2.x, /
with integer arguments is integer division unless you import division
from __future__
, and integer division rounds down as well.
int(99.999999946*100)/100
gets evaluated as
int(99.999999946*100)/100
int(9999.9999946) / 100
9999 / 100 # int rounds down
99 # integer division rounds down
The division in int(99.999999946*100)/100.0
is a float one. The result may not be precisely 99.98, but that's to be expected since 0.98 = 48 / 50 cannot be expressed in base 2.
int(99.999999946*100)/100.0
int(9999.9999946) / 100.
9999 / 100.0 # int rounds down
99.989999999999995 # floating-point division
For your last example, note the digit at the second decimal place
round(99.999999946, 2) = 100.0
round(99.989999999999995, 2) = 99.99
If you want correct (but rather slow) decimal calculation, use the decimal
module:
import decimal
d = decimal.Decimal('99.999999946')
d.quantize(decimal.Decimal('.01'), decimal.DOWN) # Decimal('99.99')
Upvotes: 2