Nachdem ich mir die Antworten auf einige ähnliche Fragen angesehen habe, scheint dies die beste Lösung für mich zu sein:
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
Meine Argumentation:
%g
wird die wissenschaftliche Notation nicht los.
>>> '%g' % 0.000035
'3.5e-05'
15 Dezimalstellen scheinen seltsames Verhalten zu vermeiden und haben viel Präzision für meine Bedürfnisse.
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
Ich hätte format(inputValue, '.15f').
stattdessen verwenden können '%.15f' % inputValue
, aber das ist etwas langsamer (~ 30%).
Ich hätte es gebrauchen können Decimal(inputValue).normalize()
, aber das hat auch ein paar Probleme. Zum einen ist es VIEL langsamer (~ 11x). Ich fand auch heraus, dass es, obwohl es eine ziemlich hohe Präzision aufweist, bei der Verwendung immer noch unter Präzisionsverlust leidet normalize()
.
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
Am wichtigsten ist, dass ich immer noch Decimal
von einem konvertieren würde, float
was dazu führen kann, dass Sie etwas anderes als die Nummer erhalten, die Sie dort eingegeben haben. Ich denke, Decimal
funktioniert am besten, wenn die Arithmetik erhalten bleibt Decimal
und die Decimal
mit einer Zeichenfolge initialisiert wird.
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
Ich bin mir sicher, dass das Präzisionsproblem von Decimal.normalize()
mithilfe der Kontexteinstellungen an die Anforderungen angepasst werden kann, aber angesichts der ohnehin langsamen Geschwindigkeit, die keine lächerliche Präzision erfordert, und der Tatsache, dass ich immer noch von einem Float konvertieren und trotzdem an Präzision verlieren würde, habe ich es nicht getan Ich glaube nicht, dass es sich gelohnt hat, sie zu verfolgen.
Ich bin nicht besorgt über das mögliche "-0" -Ergebnis, da -0.0 eine gültige Gleitkommazahl ist und es wahrscheinlich sowieso selten vorkommt, aber da Sie erwähnt haben, dass Sie das String-Ergebnis so kurz wie möglich halten möchten, Sie könnte immer eine zusätzliche Bedingung bei sehr geringen zusätzlichen Geschwindigkeitskosten verwenden.
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
3.14 == 3.140
- Sie sind die gleiche Gleitkommazahl. Im Übrigen ist 3.140000 dieselbe Gleitkommazahl. Die Null existiert überhaupt nicht.