将浮点数转换为字符串,采用位置格式(不使用科学计数法和虚假的精度)。
将浮点数转换为字符串,采用位置格式(不使用科学计数法和虚假的精度)。
我想打印一些浮点数,以便它们总是以十进制形式写入(例如12345000000000000000000.0
或0.000000000000012345
),而不是使用科学计数法,但我希望结果具有IEEE 754双精度的约15.7个有效数字,且不超过该限制。
我希望的是最理想的情况是,结果是转换为float
时仍具有相同值的最短的十进制格式字符串。
众所周知,如果指数大于15或小于-4,则float
的repr
以科学计数法写入:
>>> n = 0.000000054321654321 >>> n 5.4321654321e-08 # 科学计数法
如果使用str
,则生成的字符串仍然是科学计数法:
>>> str(n) '5.4321654321e-08'
有人建议我可以使用具有足够精度的f
标志和format
来摆脱科学计数法:
>>> format(0.00000005, '.20f') '0.00000005000000000000'
对于这个数字,它可以工作,尽管有一些额外的尾部零。但是同样的格式对于.1
失败了,它给出了超出浮点数实际机器精度的十进制数字:
>>> format(0.1, '.20f') '0.10000000000000000555'
如果我的数字是4.5678e-20
,使用.20f
仍会丢失相对精度:
>>> format(4.5678e-20, '.20f') '0.00000000000000000005'
因此,这些方法不符合我的要求。
这就引出了一个问题:以最简单和性能最好的方式打印任意浮点数的十进制格式,与repr(n)
(或Python 3上的str(n)
)中的数字相同,但始终使用十进制格式,而不是科学计数法。
也就是说,一个函数或操作,例如将浮点值0.00000005
转换为字符串'0.00000005'
;0.1
转换为'0.1'
;420000000000000000.0
转换为'420000000000000000.0'
或420000000000000000
,并将浮点值-4.5678e-5
格式化为'-0.000045678'
。
赏金期结束后:似乎至少有两种可行的方法,正如卡琳所展示的,使用字符串操作可以显著提高性能,比起我最初的算法在Python 2上。
因此,
- 如果性能很重要且需要与Python 2兼容;或者如果由于某种原因不能使用
decimal
模块,则卡琳的字符串操作方法是可行的。 - 在Python 3上,我略微更短的代码也将更快。
由于我主要在Python 3上开发,我将接受自己的答案,并授予卡琳赏金。