Birkaç benzer sorunun cevabını inceledikten sonra, bu benim için en iyi çözüm gibi görünüyor:
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
Akıl yürütmem:
%g
bilimsel gösterimden kurtulamaz.
>>> '%g' % 0.000035
'3.5e-05'
15 ondalık basamak garip davranışlardan kaçınıyor gibi görünüyor ve ihtiyaçlarım için çok fazla hassasiyete sahip.
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
Bunun format(inputValue, '.15f').
yerine kullanabilirdim '%.15f' % inputValue
, ama bu biraz daha yavaş (~% 30).
Kullanabilirdim Decimal(inputValue).normalize()
, ama bunun da birkaç sorunu var. Birincisi, çok daha yavaş (~ 11x). Ayrıca oldukça büyük bir hassasiyete sahip olmasına rağmen, kullanırken hala hassas kayıptan muzdarip olduğunu gördüm normalize()
.
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
En önemlisi, hala oraya koyduğunuz sayıdan başka bir şeyle sonuçlanmanıza neden olabilecek Decimal
birinden dönüştürüyorum float
. Ben Decimal
aritmetik kalır Decimal
ve Decimal
bir dize ile başlatıldığında en iyi çalışır düşünüyorum .
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
Ben eminim hassas sorunu Decimal.normalize()
bağlam ayarları kullanılarak gerekenlere ayarlanabilir, ancak zaten düşük hız ve saçma hassasiyete ihtiyaç duymadan ve yine de bir şamandıradan dönüştüğüm ve yine de hassasiyeti kaybettiğim düşünülürse, yapmadım takip etmeye değer olduğunu düşünmüyorum.
-0.0 geçerli bir kayan nokta sayısı olduğundan ve muhtemelen zaten nadir bir olay olacağı için olası "-0" sonucuyla ilgilenmiyorum, ancak bahsettiğinizden dolayı dize sonucunu mümkün olduğunca kısa tutmak istiyorsunuz, her zaman çok az ekstra hız maliyetiyle ekstra bir koşul kullanabilir.
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
3.14 == 3.140
- Aynı kayan nokta numarası. Bu nedenle 3.140000 aynı kayan noktalı sayıdır. Sıfır ilk etapta mevcut değildir.