我想打印一些浮点数,使它们始终以十进制形式书写(例如12345000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
或,而不是科学符号,但我希望结果具有IEEE 754双倍的最多约15.7个有效数字,而不是更多。
理想的情况是,结果是位置十进制格式的最短字符串,当转换为
float
时,仍然得到相同的值。
众所周知,如果指数大于15或小于-4,则
float
的repr
是以科学符号写成的:
>>> n = 0.000000054321654321
>>> n
5.4321654321e-08 # scientific notation
如果使用
str
,则生成的字符串仍然是科学符号:
>>> str(n)
'5.4321654321e-08'
有人建议,我可以使用带有
f
标志和足够精度的format
来摆脱科学符号:
>>> format(0.00000005, '.20f')
'0.00000005000000000000'
它适用于这个数字,尽管它有一些额外的尾随零。但
.1
的相同格式将失败,它给出的十进制数字超出了float的实际机器精度:
>>> 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'
;4200000000000000000000
转换为'42000000000000000000000000'
或420000000000000000
并将浮点值-4.5678E-5
格式化为'-0.000045678'
。
赏金期之后:看来至少有两种可行的方法,正如Karin所演示的,使用字符串操作可以实现比我在Python2上的初始算法显著的速度提升。
因此,
- 如果性能很重要并且需要Python2兼容性;或者由于某种原因不能使用
decimal
模块,那么Karin使用字符串操作的方法就是实现方法。 - 在Python 3上,我的代码稍微短一些也会更快。
不幸的是,似乎连带有float.__format__
的新式格式都不支持这一点。float
s的默认格式与repr
相同;使用f
标志时,默认情况下有6个小数位数:
>>> format(0.0000000005, 'f')
'0.000000'
然而,有一种方法可以获得所需的结果--不是最快的结果,而是相对简单的结果:
str()
或repr()
decimal
实例。decimal.__format__
支持f
标志,该标志提供所需的结果,并且与float
不同,它打印实际精度而不是默认精度。因此,我们可以创建一个简单的实用函数float_to_str
:
import decimal
# create a new context for this task
ctx = decimal.Context()
# 20 digits should be enough for everyone :D
ctx.prec = 20
def float_to_str(f):
"""
Convert the given float to a string,
without resorting to scientific notation
"""
d1 = ctx.create_decimal(repr(f))
return format(d1, 'f')
必须注意不要使用全局十进制上下文,因此为该函数构造了一个新的上下文。这是最快的方式;另一种方法是使用decimal.local_context
,但速度会慢一些,为每次转换创建一个新的线程本地上下文和一个上下文管理器。
该函数现在返回从尾数起包含所有可能数字的字符串,四舍五入到最短的等效表示:
>>> float_to_str(0.1)
'0.1'
>>> float_to_str(0.00000005)
'0.00000005'
>>> float_to_str(420000000000000000.0)
'420000000000000000'
>>> float_to_str(0.000000000123123123123123123123)
'0.00000000012312312312312313'
最后一个结果在最后一位四舍五入
正如@karin所指出的,float_to_str(42000000000000000000000.0)
并不严格符合预期的格式;它返回4200000000000000
,而不拖尾.0
。
问题内容: 我想打印一些浮点数,以使它们始终以十进制形式写(例如或,而不是科学计数法,但是我希望结果具有IEEE 754倍数的最多〜15.7的有效数字,仅此而已。 理想情况下 , __ 我想要 的结果是 位置十进制格式 的 最短 字符串,当转换为a时仍会得到相同的值 。 众所周知,如果指数大于15或小于-4,则用科学记数法写a的: 如果使用,则结果字符串再次采用科学计数法: 有人建议我可以用用标志
很多问题都解决了这个问题,但没有一个解决方案能完全满足我的需要。 我有一个数据框,有两列数字,每列10-20位。这些实际上是ID,我想将它们连接起来。看起来最好先将值转换为字符串。 然而,当使用转换时,熊猫保留了科学符号,这是不会飞的。 我尝试过的事情: 尝试:dtype arg('str')或转换器(使用)在 结果:
在我的例子中,其中一个xml标记值是"09031454866678e6"。而在中转换为json对象e被认为是科学符号,并转换为“9.031454866678E6”。 我应该如何避免这种转换并确保它被解析为字符串而不是数字? 在代码中: 其中resp是xml字符串。 设置值时失败 setobject方法如下所示 项目中使用的maven依赖项是 我期望输出与原始值“09031454866678e6”相
问题内容: 我想要这种格式 问题答案: 您需要先 解析 日期字符串(使用方法),才能 使用与格式匹配的格式获取对象。 然后使用所需的格式来 格式化 Date对象(Use 方法)以获取字符串。 输出:- 第一种格式是RFC 822 TimeZone与您的日期字符串匹配。有关在日期格式中使用的其他各种选项,请参见。
问题内容: 如何使用PEM格式的字符串创建实例?PEM格式的字符串是HTTP请求“ SSL_CLIENT_CERT”标头值。 答案 : 根据mgaert的回答,这是我在Scala中写的内容 : 问题答案: 将Base64解码为二进制,并用一些InputStream读取它,然后尝试
如何将日期字段从科学符号转换为freemarker中的数字,然后根据该日期字段的值进行sort_by? 如果我能从Freemarker文档注释中获得一些指针或任何特定的参考,我将很高兴。