Après avoir examiné les réponses à plusieurs questions similaires, cela semble être la meilleure solution pour moi:
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
Mon raisonnement:
%g
ne se débarrasse pas de la notation scientifique.
>>> '%g' % 0.000035
'3.5e-05'
15 décimales semblent éviter les comportements étranges et ont beaucoup de précision pour mes besoins.
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
J'aurais pu utiliser à la format(inputValue, '.15f').
place de '%.15f' % inputValue
, mais c'est un peu plus lent (~ 30%).
J'aurais pu l'utiliser Decimal(inputValue).normalize()
, mais cela pose également quelques problèmes. D'une part, c'est BEAUCOUP plus lent (~ 11x). J'ai également trouvé que même s'il a une assez grande précision, il souffre toujours d'une perte de précision lors de l'utilisation normalize()
.
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
Plus important encore, je serais toujours en train de convertir à Decimal
partir d'un float
qui peut vous faire finir avec autre chose que le nombre que vous avez mis là-dedans. Je pense que cela Decimal
fonctionne mieux lorsque l'arithmétique reste Decimal
et que le Decimal
est initialisé avec une chaîne.
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
Je suis sûr que le problème de précision de Decimal.normalize()
peut être ajusté à ce qui est nécessaire en utilisant les paramètres de contexte, mais compte tenu de la vitesse déjà lente et de ne pas avoir besoin d'une précision ridicule et du fait que je serais toujours en train de convertir un flotteur et de perdre de la précision de toute façon, je n'ai Je ne pense pas que cela valait la peine d'être poursuivi.
Je ne suis pas préoccupé par le résultat possible "-0" car -0.0 est un nombre à virgule flottante valide et ce serait probablement une occurrence rare de toute façon, mais comme vous avez mentionné que vous souhaitez garder le résultat de la chaîne aussi court que possible, vous pourrait toujours utiliser une condition supplémentaire à très peu de frais de vitesse supplémentaire.
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
3.14 == 3.140
- C'est le même nombre à virgule flottante. D'ailleurs, 3,140000 est le même nombre à virgule flottante. Le zéro n'existe pas en premier lieu.