2013-07-24 5 views
2

Я конвертирую float в целое число в код ниже. Но результат не подходит для никеля.int() преобразование float в python

Код:

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 

Ожидаемый результат

6 1 1 5.0 
1.0 1 

Если я явно сделать Int (5,0/5) Я получаю 1, но когда то же самое делается для переменной в моем коде, я получаю 0. Я не знаю, почему. Может кто-нибудь объяснить?

ответ

6

Числа с плавающей точкой не гарантированно место на номер, который вы ожидаете, что они могли быть просто едва сдвинулись, скажем 5.0 может быть на самом деле 4.999... и так int() обрезает/округляет вниз, вы получите свою ошибку.

Многие банки просто полностью отказаться от выпуска с плавающей точкой и просто работать с $ 1,00 = 100 Я бы посоветовал вам сделать то же самое, как это:

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) 

примечание, что это выводит 2 1 1 5, потому что это 2 квартала, 1 копейка и 1 никель = $.65

Как правило, вы хотите округлить как можно ниже, чтобы поддерживать точность, но когда вы работаете с деньгами, я думаю, что работа полностью с ints делает кошмар поплавков быстрее уходить.

Кроме того, так как вы используете 2.6, вам нужно будет бросить в int() потому что round() не возвращает целое число до 3,1

+0

Я бы даже избежал 26.65 и пошел прямо на 2500 и 2665. –

+0

@ LennartRegebro не хотел менять свои входы, но да, я бы сделал что-то похожее – Stephan

1

Когда вы int(x), он всегда округляет вниз, то есть, если вы делаете int(4.9999) вы получите 4. Рассмотрите возможность использования int(round(x)) вместо

EDIT:

Подождите ... если вы умноженная на 100, почему вы вообще используете поплавки? Для чего вам нужны десятичные знаки? Почему бы просто не превратить центы в int после умножения на 100, а затем избавиться от всей этой бессмысленной поплавки?

+0

'int (round (x))' будет округлять в тех случаях, когда он не должен, используя слишком много монет. – user2357112

+0

Проблема здесь заключается в неадекватности его чисел с плавающей запятой. Вместо округления внутри литья типа круглые центы каждый раз, когда вы его устанавливаете. Таким образом, он становится «cents = round (cents% 25)». Вчера я столкнулся с аналогичным вопросом, который может вам помочь (http://stackoverflow.com/questions/17779336/python-code-not-working-confusion-about-if-statement/17779465#17779465) – scohe001

+0

округление дает результат как '7 1 1', в то время как это должно быть' 6 1 1' – misguided

3

Floating point numbers cannot represent all real numbers.

Каждый раз, когда вы делаете что-либо с числами с плавающей запятой, вы приближаетесь к точному результату ближайшей вещью, которую может представлять ваше представление с плавающей запятой. Когда вы пишете

26.65 

Python фактически использует

26.64999999999999857891452847979962825775146484375 

Когда вы делаете математику с числами с плавающей запятой, результат округляется до ближайшего представимому числа. print обрежет числа с плавающей запятой до 12 знаков после запятой, поэтому небольшие погрешности не видны, но когда вы вычислить

int(cents/5) 

cents фактически 4.999999999999858 и cents/5 является 0.9999999999999716, который округляется до 0.

+0

как мы можем проверить значение центов? когда я распечатал его, он показывает 5.0 – misguided

+1

@misguided: 'print repr (центы)'. Лично я считаю, что по умолчанию 12 цифр отображаемой точности являются ошибкой. Если люди хотят 12 цифр, они могут получить это с форматированием строки. – user2357112

2

Другие пользователи не объяснили, как плавающей точки являются неточными. В вашем случае, рекомендуется использовать Decimal для более точных расчетов:

>>> 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') 

Примите к сведению строк для чисел, создающих оригинальный actual и paid. Они нужны.

Смежные вопросы