Как плюсить один в хвосте на число с плавающей точкой в Python?
Есть ли простой и прямой способ добавить "один" в число с плавающей точкой в Python?
Я имею в виду это:
if a == 0.0143:
a = plus(a)
assert a == 0.0144
def plus(a):
sa = str(a)
index = sa.find('.')
if index<0:
return a+1
else:
sb = '0'*len(sa)
sb[index] = '.'
sb[-1] = 1
return a+float(sb)
Это не то, что я хочу, потому что он дает мне 0,0144000000001.
Ответы
Ответ 1
Как вы заметили, не все десятичные числа могут быть представлены точно как float:
>>> Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> Decimal(0.2)
Decimal('0.200000000000000011102230246251565404236316680908203125')
>>> Decimal(0.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
>>> Decimal(0.4)
Decimal('0.40000000000000002220446049250313080847263336181640625')
>>> Decimal(0.5)
Decimal('0.5')
Поскольку вы работаете со свойствами десятичных чисел, используйте модуль decimal
, который точно их реализует:
from decimal import Decimal
def plus(n):
return n + Decimal('10') ** n.as_tuple().exponent
И демо:
>>> n = Decimal('0.1239')
>>> plus(n)
Decimal('0.1240')
Вы должны представить число как строку, так как представление его как float потеряет точность.
Недостатком является то, что использование decimal
сделает вашу функцию plus
примерно в 20-30 раз медленнее, чем если бы вы использовали операции с плавающей запятой, но это была стоимость точности.
Ответ 2
Ответ на Blender, безусловно, хороший ответ, но если вы настаиваете на использовании floats
, я считаю, что простой способ сделать это:
-
Найдите x для 10 ** x
, который может умножить ваш float на целое число.
-
Добавьте один к увеличенному номеру.
-
Разделите свой предыдущий множитель.
Так выглядит:
n = 0.125
e = len(str(n)) - 2
temp_n = n * 10 ** e
temp_n += 1
n = temp_n / 10 ** e
print n
EDIT:
В предыдущем script все пошло не так, когда число было очень длинным. Результаты усекаются на str()
и print
, поэтому я немного изменил script:
n = 0.1259287345982795
e = len(repr(n)) - 2
temp_n = n * 10 ** e
temp_n += 1
n = temp_n / 10 ** e
print repr(n)
Ответ 3
n = n + 1/10**(len(repr(n)) - 2)