简体   繁体   中英

int() conversion of float in python

I am conversting a float to integer in the below code. But , the resultant output is not correct for nickels.

Code:

actual = 25
paid = 26.65
cents = (paid-actual)*100
quarters = int(cents/25)
cents = cents %25
dimes = int(cents/10)
cents = cents %10
nickels = int(cents/5)
print quarters, dimes, nickels,cents
print 5.0/5,int(5.0/5)

Ouput:

6 1 0 5.0
1.0 1

Expected output

6 1 1 5.0
1.0 1

If i explicitly do int(5.0/5) I get 1 , but when the same is done assigned to a variable in my code, I get 0 . I am not sure why. Can someone explain ?

Floating point numbers are not guaranteed to be spot on the number you expect, they could just be barely off, say 5.0 might actually be 4.999... and since int() truncates/rounds down, you get your error.

Many banks just completely give up on the floating point issue and just work with $1.00 = 100 I would advise you do the same, like this:

actual = 25
paid = 26.65
cents = int(round(paid*100)) #Turns 26.65 into 2665 before you do any float math
dollars = cents / 100
cents %= 100
quarters = cents / 25
cents %= 25
dimes = cents / 10
cents %= 10
nickels = cents / 5
print quarters, dimes, nickels,cents
print 5.0/5,int(5.0/5)

note that this outputs 2 1 1 5 because that's 2 quarters, 1 dime, and 1 nickel = $.65

Typically you want to round as LATE as possible to maintain precision, but when you are working with money, I think working entirely with ints makes the nightmare of floats go away faster.

Also, since you are using 2.6, you will need to cast to int() because round() doesn't return an integer until 3.1

Floating point numbers cannot represent all real numbers .

Every time you do anything with floating-point numbers, you are approximating the exact result by the closest thing your floating-point representation can represent. When you write

26.65

Python actually uses

26.64999999999999857891452847979962825775146484375

When you do math with floating point numbers, the result is rounded to the nearest representable number. print truncates floating-point numbers to 12 decimal places, so the small inaccuracies aren't visible, but when you compute

int(cents/5)

cents is actually 4.999999999999858 , and cents/5 is 0.9999999999999716 , which rounds down to 0 .

Other users have explained how floating points are inexact. In your case, consider using Decimal for more precise calculations:

>>> from decimal import Decimal
>>> actual = Decimal('25')
>>> paid = Decimal('26.65')
>>> actual,paid
(Decimal('25'), Decimal('26.65'))
>>> cents = (paid-actual)*100
>>> cents
Decimal('165.00')
>>> quarters = int(cents/25)
>>> cents = cents % 25
>>> dimes = int(cents/10)
>>> cents = cents %10
>>> nickels = int(cents/5)
>>> print quarters, dimes, nickels,cents
6 1 1 5.00
>>> cents
Decimal('5.00')

Take note of the strings for the numbers creating the original actual and paid . They're required.

When you do int(x) , it ALWAYS rounds down, meaning if you do int(4.9999) you'll get 4. Consider using int(round(x)) instead

EDIT:

Wait...if you've multiplied by 100, why are you even using floats at all? What do you need the decimals for? Why not just turn cents into an int after you multiply by 100 and then get rid of all of this float nonsense?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM