How to round to two decimal places in python? [duplicate] - python

This question already has answers here:
How to round to 2 decimals with Python? [duplicate]
(21 answers)
Closed last year.
Im trying to calculate a bill in python for hw. Cant figure out how to round the numbers to two decimal places. Here's what I have so far. Every time I try the round function, it doesnt work and gives me an error message. Help?!
ss_cost = 3.95 * 2
hb_cost = 8.95 * 2
ds_cost = 2.50 * 2
subtotal = (ss_cost) + (hb_cost) + (ds_cost)
tax = (round(subtotal * 0.0475), %.2)
print (tax)`

You missplaced the %.2:
tax = (round(subtotal * 0.0475, 2))
And you don't need the %.

round(number[, ndigits])
Return number rounded to ndigits precision after the decimal point. If ndigits is omitted or is None, it returns the nearest integer to its input.
For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2). Any integer value is valid for ndigits (positive, zero, or negative). The return value is an integer if ndigits is omitted or None. Otherwise, the return value has the same type as number.
When it comes to amounts, you shouldn't use round, it's better to use decimal.
from decimal import Decimal
ss_cost = 3.95 * 2
hb_cost = 8.95 * 2
ds_cost = 2.50 * 2
subtotal = (ss_cost) + (hb_cost) + (ds_cost)
tax = Decimal(subtotal * 0.0475).quantize(Decimal("0.00"))
print (tax)
# 1.46

Related

How to round number to one decimal places python? [duplicate]

This question already has answers here:
python incorrect rounding with floating point numbers
(4 answers)
Closed 4 months ago.
I'm trying to round my numbers to 1 decimal places. This could be with any number with many decimal places or no decimal places.
But now I'm trying to go with 8.25 as an example because when I try rounding it it always be cut or rounded to 8.2 but I'm looking for it to be 8.3 . Pls help
print(round(result,1)) #result -> 8.2
"{:.1f}".format(result) #result -> 8.2 I was thinking about adding 0.05 to it and cut for 1 decimal place but I feel like it might affect the other number since it could be any number
import math
def round_up(n, decimals=0):
multiplier = 10 ** decimals
return math.ceil(n * multiplier) / multiplier
print(round_up(8.25, 1))
output: 8.3
You can still use round().
result = 8.2546535
print(round(result,2))
Output
8.25
If you always want to round up you can use math.ceil()
import math
math.ceil(8.211234 * 10) / 10
Result
8.3

Python print questions related to float

print("%.5f" % 5.1234567890) output is 5.12346
i am not understanding why 5 is not printed in output in precision field. after 4 the 6 is printed directly. why?
You limit the number of digits in fractional part to 5 digits. When you do that it rounds the number up or down based on number after the last digit. In your case, the fifth digit of the fractional part is 5 and after that is 6. So it rounds the number 5 up.
The number you type after the dot limits the float digits after the decimal point. so your command will prints the number and the first 5 digits of his decimal part.
I don't think there is anything in the math library to do this, since obviously normal people would round that number up.
But if you are really trying to round down, for whatever reason, you would need to build a function or import some other library someone else made to do it.
You can also create a function do it, for example:
import math
def round_decimals_down(number:float, decimals:int=2):
if not isinstance(decimals, int):
raise TypeError("A")
elif decimals < 0:
raise ValueError("B")
elif decimals == 0:
return math.floor(number)
factor = 10 ** decimals
return math.floor(number * factor) / factor
valueA = 5.1234567890
roundA = round_decimals_down(valueA, 5)
print(roundA)
output: 5.12345
Let me know if that is what you were trying to accomplish.

Decimal Precision in Python [duplicate]

This question already has answers here:
Precision of decimals in Python
(1 answer)
Float sum broken? [duplicate]
(2 answers)
Limiting floats to two decimal points
(35 answers)
Closed 4 years ago.
When I run the code
b = 7**7
I get b as 823543
But when I run
b= 823543.0**(1.0/7.0)
It gives me b as 6.999999999999999
If it is something as simple as 4**(1/2) it returns 2.
My question is why doesn't python just return a perfect 7?
Also I was doing this to check if a number can be written n can be written in the form p^q where p>0 and q>1 to do so I did this:
def isPower(self, A):
possible = 0 # Integer value to check if it is possible , 0 assuming it is false initally
if(A==1):
return 1
for i in xrange(2,A-1):
res = float(A)**(1.0/float(i)) #Check if it has sqaure root or cube root up untill A-1
if(res.is_integer()): #If taking the power gives me whole number then saying it is possible
possible = 1
break
return possible
This logic fails with higher numbers like 823543 because the power returns a imprecise value how would I solve this?
You're not using Decimals - you're using floats. They trade off accuracy for speed.
Try this;
from decimal import Decimal
b = 7 ** 7 # 823543
a = Decimal(1) / Decimal(7)
b ** a # returns (for me) Decimal('7.000000000000000000000000004')
Why not rounding:
>>> b= 823543**(1/7)
>>> round(b)
7
>>>
Now you've got 7 (seven)
You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic.
In short: floating point numbers are represented as mantissa and exponent. Something like
0.1234 * 10^1
Where 1234 is the mantissa (the exponent is represented in 2-complement, if I recall correctly)
This means some integer numbers cannot be represented accurately as floats.
You can represent 7 and 823543 exactly as floats, but I don't think that works for 1/7 (don't have a piece of paper at hand): https://www.h-schmidt.net/FloatConverter/IEEE754.html
Also, take into consideration how the n-the root is calculated.

Determine how many decimal digits of a float are precise

The error below occurs on the 14th decimal:
>>> 1001*.2
200.20000000000002
Here* the error occurs on the 18th decimal digit:
>>> from decimal import Decimal
>>> Decimal.from_float(.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
# ^
# |_ here
*Note: I used Fraction since >>> 0.1 is displayed as 0.1 in the console, but I think this is related to how it's printed, not how it's stored.
Questions:
Is there a way to determine on which exactly decimal digit the error will occur?
Is there a difference between Python 2 and Python 3?
If we assume that the size of the widget is stored exactly, then there are 2 sources of error: the conversion of size_hint from decimal -> binary, and the multiplication. In Python, these should both be correctly rounded to nearest, so each should have relative error of half an ulp (unit in the last place). Since the second operation is a multiplication we can just add the bounds to get a total relative error which will be bounded 1 ulp, or 2-53.
Converting to decimal:
>>> math.trunc(math.log10(2.0**-53))
-15
this means you should be accurate to 15 significant figures.
There shouldn't be any difference between Python 2 and 3: Python has long been fairly strict about floating point behaviour, the only change I'm aware of is the behaviour of the round function, which isn't used here.
To answer the decimal to double-precision floating-point conversion part of your question...
The conversion of decimal fractions between 0.0 and 0.1 will be good to 15-16 decimal digits (Note: you start counting at the first non-zero digit after the point.)
0.1 = 0.1000000000000000055511151231257827021181583404541015625 is good to 16 digits (rounded to 17 it is 0.10000000000000001; rounded to 16 it is 0.1).
0.2 = 0.200000000000000011102230246251565404236316680908203125 is also good to 16 digits.
(An example only good to 15 digits:
0.81 = 0.810000000000000053290705182007513940334320068359375)
I'd recommend you take a read to pep485
Using == operator to compare floating-point values is not the right way to go, instead consider using math.isclose or cmath.isclose, here's a little example using your values:
try:
from math import isclose
v1 = 101 * 1 / 5
v2 = 101 * (1 / 5)
except:
v1 = float(101) * float(1) / float(5)
v2 = float(101) * (float(1) / float(5))
def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
print("v1==v2 {0}".format(v1 == v2))
print("isclose(v1,v2) {0}".format(isclose(v1, v2)))
As you can see, I'm explicitly casting to float in python 2.x and using the function provided in the documentation, with python 3.x I just use directly your values and the provided function from math module.

Python 2 decimals Points [duplicate]

This question already has answers here:
Why does the division get rounded to an integer? [duplicate]
(13 answers)
Closed 6 years ago.
I have a quick question in terms of decimals points in Python 2.
Here is the code in Python 2:
a = 1500/1589
print (round(a,2))
#0.0
I thought it would print out a = 0.94 as it did in Python 3. I am just wondering how I could get 2 decimals for my answer.
You need to specify that at least one of the inputs to the division is a floating point number by adding an explicit decimal point.
a = 1500. / 1589
print round(a, 2)
# 0.94
If you do not do this, both 1500 and 1589 are treated as integers and the result of 1500/1589 is required to be an integer (0) as well
1500 / 1589
# 0
print round(1500 / 1589, 2)
# 0.0
As a side note, if you want to print a number with two decimal places, a far easier method is to create a formatted string:
print '%0.2f' % (1500. / 1589)
# 0.94
print '{:.2}'.format(1500. / 1589)
# 0.94
That's because you're making an integer division. For instance do:
a = 1500.0/1589.0
print round(a,2)
Or if you have integers as input:
a = float(1500)/float(1589)
print round(a,2)

Categories

Resources