Переглянувши відповіді на кілька подібних питань, це здається для мене найкращим рішенням:
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
Мої міркування:
%g
не позбавляється від наукових позначень.
>>> '%g' % 0.000035
'3.5e-05'
15 десяткових знаків, схоже, уникають дивної поведінки і мають багато точності для моїх потреб.
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
Я міг би використати format(inputValue, '.15f').
замість цього '%.15f' % inputValue
, але це трохи повільніше (~ 30%).
Я міг би скористатися Decimal(inputValue).normalize()
, але це також має кілька питань. Для одного це НАБІЛЬШЕ повільніше (~ 11x). Я також виявив, що хоча він має досить велику точність, він все ще страждає від втрати точності при використанні normalize()
.
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
Найголовніше, що я все-таки переходжу до Decimal
того, float
що може змусити вас опинитися щось інше, ніж число, яке ви вводите туди. Я думаю, що Decimal
найкраще працює, коли арифметика залишається в Decimal
і Decimal
ініціалізується рядком.
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
Я впевнений, що питання точності Decimal.normalize()
можна пристосувати до того, що потрібно за допомогою параметрів контексту, але враховуючи і без того малу швидкість і не потребуючи смішної точності, а також те, що я все одно перетворююся з поплавця і втрачаю точність все одно, я не став Я думаю, що це варто було переслідувати.
Я не переймаюся можливим результатом "-0", оскільки -0.0 є дійсним номером з плаваючою комою, і це, мабуть, буде рідкісним випадком, але оскільки ви згадали, що хочете зберегти результат рядка якомога коротше, ви завжди можна використовувати додатковий умовний при дуже невеликій додатковій швидкості.
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
3.14 == 3.140
- Вони однакові з плаваючою комою. У цьому питанні 3.140000 - це те саме число з плаваючою комою. Нуль не існує в першу чергу.