Seems like you need the floor:
import math
math.floor(a * 100)/100.0
# 28.26
Answer from akuiper on Stack OverflowSeems like you need the floor:
import math
math.floor(a * 100)/100.0
# 28.26
It seems you want truncation, not rounding.
A simple way would be to combine floor division // and regular division /:
>>> a = 28.266
>>> a // 0.01 / 100
28.26
Instead of the regular division you could also multiply (as noted in the comments by cmc):
>>> a // 0.01 * 0.01
28.26
Similarly you could create a function to round down to other more/less decimals. But because floats are inexact numbers, this can lead to inaccuracies.
def round_down(value, decimals):
factor = 1 / (10 ** decimals)
return (value // factor) * factor
print(round_down(28.266, 2))
# 28.26
But as said it's not exactly exact:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12.0
1 12.3
2 12.33
3 12.333
4 12.333300000000001 # weird, but almost correct
5 12.33332 # wrong
6 12.33333
7 12.33333
There are other (more precise) approaches though:
A solution using the fraction module
A fraction can represent a decimal number much more exact than a float. Then one can use the "multiply, then floor, then divide" approach mentioned by Psidom but with significantly higher precision:
import fractions
import math
a = 28.266
def round_down(value, decimals):
factor = 10 ** decimals
f = fractions.Fraction(value)
return fractions.Fraction(math.floor(f * factor), factor)
print(round_down(28.266, 2))
# 1413/50 <- that's 28.26
And using the test I did with the floats:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12
1 123/10
2 1233/100
3 12333/1000
4 123333/10000
5 1233333/100000
6 1233333/100000
7 1233333/100000
However creating a Fraction will not magically fix an inexact float, so typically one should create the Fraction from a string or a "numerator-denominator pair" instead of from float.
A solution using the decimal module
You could also use the decimal module, which offers a variety of rounding modes, including rounding down.
For this demonstration I'm using a context manager to avoid changing the decimal rounding mode globally:
import decimal
def round_down(value, decimals):
with decimal.localcontext() as ctx:
d = decimal.Decimal(value)
ctx.rounding = decimal.ROUND_DOWN
return round(d, decimals)
print(round_down(28.266, 2)) # 28.26
Which gives more sensible results for the rounding:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12
1 12.3
2 12.33
3 12.333
4 12.3333
5 12.33333
6 12.333330
7 12.3333300
As with Fraction a Decimal should be created from a string to avoid the intermediate inexact float. But different from Fraction the Decimal have limited precision, so for values with lots of significant figures it will also become inexact.
However "rounding down" is just one of the available options. The list of available rounding modes is extensive:
Rounding modes
decimal.ROUND_CEILINGRound towards Infinity.
decimal.ROUND_DOWNRound towards zero.
decimal.ROUND_FLOORRound towards -Infinity.
decimal.ROUND_HALF_DOWNRound to nearest with ties going towards zero.
decimal.ROUND_HALF_EVENRound to nearest with ties going to nearest even integer.
decimal.ROUND_HALF_UPRound to nearest with ties going away from zero.
decimal.ROUND_UPRound away from zero.
decimal.ROUND_05UPRound away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise round towards zero.
Videos
Hello,
Does anyone know how to limit or round a float to only two decimals without rounding up?
for example,
if the number is 3.149, then I want the output to be 3.14. If the number is 3.0, then the output must be 3.00
thank you
You can use the round function, which takes as its first argument the number and the second argument is the precision after the decimal point.
In your case, it would be:
answer = str(round(answer, 2))
Using str.format()'s syntax to display answer with two decimal places (without altering the underlying value of answer):
def printC(answer):
print("\nYour Celsius value is {:0.2f}ºC.\n".format(answer))
Where:
:introduces the format spec0enables sign-aware zero-padding for numeric types.2sets the precision to2fdisplays the number as a fixed-point number
Neither Python built-in nor numpy's version of ceil/floor support precision.
One hint though is to reuse round instead of multiplication + division (should be much faster):
def my_ceil(a, precision=0):
return np.round(a + 0.5 * 10**(-precision), precision)
def my_floor(a, precision=0):
return np.round(a - 0.5 * 10**(-precision), precision)
UPD:
As pointed out by @aschipfl, for whole values np.round will round to the nearest even, which will lead to unexpected results, e.g. my_ceil(11) will return 12. Here is an updated solution, free of this problem:
def my_ceil(a, precision=0):
return np.true_divide(np.ceil(a * 10**precision), 10**precision)
def my_floor(a, precision=0):
return np.true_divide(np.floor(a * 10**precision), 10**precision)
This seems to work (needs no import and works using the // operator which should be faster than numpy, as it simply returns the floor of the division):
a = 2.338888
n_decimals = 2
a = ((a*10**n_decimals)//1)/(10**n_decimals)
Since this post might be here for a while, lets also point out python 3 syntax:
"{:.2f}".format(5)
You could use the string formatting operator for that:
>>> '%.2f' % 1.234
'1.23'
>>> '%.2f' % 5.0
'5.00'
The result of the operator is a string, so you can store it in a variable, print etc.