将浮点数转换为特定精度,然后复制到字符串中。

189

我有一个浮点数,比如 135.12345678910。我想要将该值连接到一个字符串中,但只想要 135.123456789。使用 print 命令,我可以轻松做到这一点,例如:

print "%.9f" % numvar

使用numvar表示我的原始数字。有没有简单的方法可以做到这一点?


3
“% exactly does that”翻译为“% 确切地实现了这个功能”。“%”不是print函数的一部分,而是字符串的一部分。请参阅Python文档中的链接:http://docs.python.org/2/library/stdtypes.html#string-formatting-operations。 - michael_s
8个回答

248

对于 Python < 3 的版本(例如2.6 [请参见评论]或2.7),有两种方法可以这样做。

# Option one
older_method_string = "%.9f" % numvar

# Option two
newer_method_string = "{:.9f}".format(numvar)

请注意,对于Python版本在3以上(例如3.2或3.3),推荐选项二(参见此链接)

有关选项二的更多信息,请参阅Python文档中有关字符串格式化的此链接

有关选项一的更多信息,请使用此链接(包含有关各种标志的信息)即可。

Python 3.6(于2016年12月正式发布)添加了f字符串字面量,在此处查看更多信息,它扩展了str.format方法(使用花括号,如f"{numvar:.9f}"解决原始问题)即:

# Option 3 (versions 3.6 and higher)
newest_method_string = f"{numvar:.9f}"

解决问题。查看@Or-Duan的答案以获取更多信息,但这种方法快速


1
选项二应该是 newer_method_string = "{:.9f}".format(numvar) - 注意需要使用 : 来分隔字段和格式化。我已经在2.7.5上测试过了。 - Caltor
1
对于Python 2.6,选项二应该是newer_method_string = "{0:.9f}".format(numvar)--请注意此旧版本的field_name需要0。 - ttq
我想要有效数字,而不是仅仅根据{v.:3f}盲目截断。如何获取有效数字? - Charlie Parker
@CharlieParker 我建议使用指数表示法,例如 {:12.5e}。在文档的这个子部分中有更多信息(https://docs.python.org/2/library/string.html#format-specification-mini-language)。 - jyalim

78

除了9以外,是否有指定精度的语法? - Minh Nghĩa
@MinhNghĩa 只需将“9”更改为您想要的任何数字即可。 - Or Duan
我指的是任意精度,例如 n - Minh Nghĩa
1
你是指在运行时计算的动态数字吗?如果是,那么你将不得不使用 round - Or Duan

61
使用 round
>>> numvar = 135.12345678910
>>> str(round(numvar, 9))
'135.123456789'

13

如果直到运行时才知道精度,那么这种格式选项会很有用:

>>> n = 9
>>> '%.*f' % (n, numvar)
'135.123456789'

6
如果您更喜欢使用.format方法,请注意可以通过嵌套参数来实现,例如:'{:.{n}f}'.format(numvar,n=n) - nivk

8

它不是打印程序来进行格式化处理的,而是字符串的属性,所以你只需要使用

newstring = "%.9f" % numvar

或者使用新的格式化样式。valueString = "{:.9f}".format(number) - Zaren

2

要设置精度为9位小数,请执行以下操作:

print "%.9f" % numvar

返回精度为2位的结果:

print "%.2f" % numvar 

返回精度为2位的浮点转换值:

numvar = 4.2345
print float("%.2f" % numvar) 

0

只要小数点的位数在范围内,它就能正常工作;之后就取决于硬件。超过第14位小数,我无法使其匹配。这些值来自数字高程文件中的纬度。

https://docs.python.org/3/tutorial/floatingpoint.html

lat1 = -81.0016666666670072 
lat2 = -81.0016666666670062
assert lat1 == lat2 # no asserion error :(

# try with Decimal
from decimal import *
getcontext().prec = 16
assert Decimal(lat1) == Decimal(lat2) # no asserion error :(

# Lets see string representation
print(f"{lat1:.16f}", f"{lat2:.16f}")
# -81.0016666666670062 -81.0016666666670062 :( Perils of Float

# Lets see how it is store in hardware
print(lat1.hex(), lat2.hex())
# -0x1.4401b4e81b500p+6 -0x1.4401b4e81b500p+6

# 14-th position it is able to identify 
lat1 = -81.0016666666670162 
lat2 = -81.0016666666670062
#-0x1.4401b4e81b501p+6 -0x1.4401b4e81b500p+6
print(lat1.hex(), lat2.hex())
assert lat1 == lat2 # assertion error :)

-2

str函数存在一个bug,请尝试以下方法。你会看到输出结果为'0,196553',但正确的输出应该是'0,196554'。因为str函数的默认值是ROUND_HALF_UP。

>>> value=0.196553500000 
>>> str("%f" % value).replace(".", ",")

2
.,有什么区别?这和pauliwago的问题有什么关系? - Peter Mortensen
@PeterMortensen 我认为使用列表分隔符(也称逗号:,)作为小数分隔符是一个令人困惑的欧洲标准。 - Cameron Tacklind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接