Как плюсить один в хвосте на число с плавающей точкой в ​​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)