Setelah mencari jawaban atas beberapa pertanyaan serupa, ini tampaknya menjadi solusi terbaik bagi saya:
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
Alasan saya:
%g
tidak menghilangkan notasi ilmiah.
>>> '%g' % 0.000035
'3.5e-05'
15 tempat desimal tampaknya menghindari perilaku aneh dan memiliki banyak ketepatan untuk kebutuhan saya.
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
Saya bisa menggunakan format(inputValue, '.15f').
bukan '%.15f' % inputValue
, tapi itu sedikit lebih lambat (~ 30%).
Saya bisa menggunakan Decimal(inputValue).normalize()
, tetapi ini memiliki beberapa masalah juga. Untuk satu, itu BANYAK lebih lambat (~ 11x). Saya juga menemukan bahwa meskipun memiliki presisi yang sangat bagus, ia masih mengalami kehilangan presisi saat menggunakan normalize()
.
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
Yang paling penting, saya masih akan mengkonversi Decimal
dari float
yang dapat membuat Anda berakhir dengan sesuatu selain nomor yang Anda masukkan di sana. Saya pikir Decimal
bekerja paling baik ketika aritmatika tetap Decimal
dan Decimal
diinisialisasi dengan string.
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
Saya yakin masalah presisi Decimal.normalize()
dapat disesuaikan dengan apa yang diperlukan menggunakan pengaturan konteks, tetapi mengingat kecepatan yang sudah lambat dan tidak memerlukan presisi yang konyol dan fakta bahwa saya masih akan mengkonversi dari float dan kehilangan presisi, saya tidak pikir itu layak dikejar.
Saya tidak khawatir dengan kemungkinan hasil "-0" karena -0.0 adalah angka floating point yang valid dan mungkin akan menjadi kejadian yang jarang terjadi, tetapi karena Anda memang menyebutkan Anda ingin menjaga hasil string sesingkat mungkin, Anda selalu dapat menggunakan persyaratan ekstra dengan biaya kecepatan ekstra yang sangat kecil.
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
3.14 == 3.140
- Mereka nomor floating point yang sama . Dalam hal ini 3.140000 adalah angka floating-point yang sama. Angka nol tidak ada sejak awal.