如何将浮点数打印为包括尾随0的n位小数?

58

我需要将浮点数打印或转换为15位小数的字符串,即使结果有许多尾随的0,例如:

1.6 变成 1.6000000000000000

我尝试了 round(6.2,15),但它返回 6.2000000000000002 并添加了一个舍入误差。

我也看到在线上有很多人将浮点数放入字符串中,然后手动添加尾随0,但那似乎不太好……

那么,最好的方法是什么呢?


5
顺便提一下,但最后的2不是一个精度误差。像许多其他实数一样,数字6.2在计算机中不能用浮点变量来精确表示。更多信息请参见http://docs.python.org/tutorial/floatingpoint.html和https://dev59.com/WXNA5IYBdhLWcg3wHp6B。 - mtrw
3
@mtrw,我认为你可以称之为舍入误差-输入值被舍入到最接近的二进制数。 - Mark Ransom
5个回答

82

对于Python版本在2.6+和3.x中

您可以使用 str.format 方法。例如:

>>> print('{0:.16f}'.format(1.6))
1.6000000000000001

>>> print('{0:.15f}'.format(1.6))
1.600000000000000

注意第一个例子末尾的1是舍入误差;这是因为十进制数1.6的精确表示需要无限多的二进制位。由于浮点数具有有限的位数,因此该数字会被舍入到附近但不相等的值。

对于Python 2.6及之前版本(至少支持2.0)

您可以使用"模数格式化"语法(这也适用于Python 2.6和2.7):

>>> print '%.16f' % 1.6
1.6000000000000001

>>> print '%.15f' % 1.6
1.600000000000000

1
+1. 此答案在Python 2.7及以上版本中可用。在Python 2.6中,这应该为'{0:.16f}'.format(x),但旧版本Python的情况不确定。 - mtrw
@jonathantopf 你使用的是哪个版本的Python?正如@mtrw在上面的评论中指出的那样,如果你使用的是Python 2.6,你需要使用位置参数(即该评论代码中的“0”)。如果你使用的是Python 3.0,这也是正确的。 - David Alber
@mtrw 我更新了答案,使用了位置参数,并包括了针对2.6之前版本解释器的“模数格式化”。 - David Alber
虽然这个答案在技术上是正确和有信息的,但我觉得它忽略了问题的重点。如果你打印print '{0:.15f}'.format(600.2),你会注意到右边已经出现了非零数字,而且你的数字越大,小数部分中就会看到更多的“噪音”。如果你真的关心保持15位精度,请参考我的关于使用decimal模块的答案。 - dkamins
我因缺少括号而在Python 3.7中遇到语法错误。 我已经添加了它们。 - paullb
显示剩余2条评论

16

在现代的 Python >=3.6 中,最清晰的方法是使用带有字符串格式化的 f-string:

>>> var = 1.6
>>> f"{var:.15f}"
'1.600000000000000'

5

3
我们可以使用format()来打印小数点后的数字。摘自http://docs.python.org/tutorial/floatingpoint.html
>>> format(math.pi, '.12g')  # give 12 significant digits
'3.14159265359'

>>> format(math.pi, '.2f')   # give 2 digits after the point
'3.14'

1
'.12g' 并不总是给出 12 个有效数字:>>> f'{1.23456:.12g}' '1.23456' - KeithB

3

我猜这本质上是把它放在一个字符串中,但这样可以避免四舍五入误差:

import decimal

def display(x):
    digits = 15
    temp = str(decimal.Decimal(str(x) + '0' * digits))
    return temp[:temp.find('.') + digits + 1]

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