将浮点数限制在两位小数。

2348

12
嗯...你是在尝试表示货币吗?如果是的话,你不应该使用浮点数表示美元。你可以使用浮点数表示便士,或者你正在尝试建模的最小通用货币单位,但最佳实践是使用十进制表示法,正如HUAGHAGUAH在他的答案中建议的那样。 - SingleNegationElimination
89
不要将货币表示为浮点数,而应该使用整数来表示分或美分数额。浮点数不够精确,而整数能够准确地表示货币数值。因此,整数是正确表示货币的方法。 - Davoud Taghawi-Nejad
5
基本上不需要(大多数情况下),用以分为单位的整数或者以便士为单位是很可靠的。这是代表货币的行业标准。如果你知道你在做什么,对浮点算术和Python的十进制类有充分的了解,可能会使用十进制表示法。但这取决于你的问题。你需要任意精度的小数吗?还是只需要两位数字?如果是两位数字:整数足矣。它会避免让你陷入麻烦。出处:我曾在银行软件咨询公司工作过。 - Davoud Taghawi-Nejad
35
我可能来得有点晚了,但我想问一下,Python的开发者已经解决了这个问题吗?因为当我执行round(13.949999999999999, 2)时,结果就是13.95。我已经在Python 2.7.6和3.4中尝试了一下,都可以工作。不确定2009年是否已经有Python 2.7版本。也许这只是Python 2.5的问题? - bad_keypoints
10
是的,Python 2.7.0+ 已经解决了舍入问题。更多信息请参见我的回答 - hynekcer
显示剩余6条评论
37个回答

58

您可以修改输出格式:

>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95

55

使用Python<3(例如2.6或2.7),有两种方法可以这样做。

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

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

请注意,对于Python 3及以上版本(例如3.2或3.3),选项二是首选方法。

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

有关选项一的更多信息,请参阅此链接,其中包含有关各种标志的信息。

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


你如何表示一个整数?如果我使用"{i3}".format(numvar),会出现错误。 - skytux
这是我的意思:如果 numvar=12.456,那么 "{:.2f}".format(numvar) 会得到 12.46,但 "{:2i}".format(numvar) 会报错,我期望得到的是 12 - skytux

44
你可以使用Python中的格式化运算符将值四舍五入到两位小数:

您可以使用format操作符在Python中将值四舍五入到两个小数点:

print(format(14.4499923, '.2f')) // The output is 14.45

6
这个函数返回一个字符串。 - Jemshit Iskenderov
如果我们只想截断,该如何实现。 - Arpan Saini
运算符?它不是一个函数吗? - Peter Mortensen

35

正如Matt指出的那样,Python 3.6提供了f-strings,并且它们还可以使用嵌套参数

value = 2.34558
precision = 2
width = 4

print(f'result: {value:{width}.{precision}f}')

这将显示result: 2.35


31

在Python 2.7中:

a = 13.949999999999999
output = float("%0.2f"%a)
print output

1
这完全没有帮助。output的值与a完全相同,因此您可以直接在最后一行写print a而不是print output - Mark Dickinson
@MarkDickinson 你能再试一次吗?因为在我的编译器中它按预期运行。 - Shashank Singh
1
你没有理解我的意思。是的,你的代码打印出了 13.95。但是在 Python 2.7 中,对于这个特定的 a 值,print a 也会打印出相同的结果,所以格式化步骤的目的并不是很清楚。 - Mark Dickinson
@MarkDickinson 我已经编辑了代码。我同意'print a'打印的值与"print output"相同。但是,如果你比较"a==output",结果将是"False",因为格式化步骤会将浮点值"a"四舍五入到两个小数点。 - Shashank Singh
1
你是否真的尝试过针对你所展示的代码进行a == output操作?这在我的环境中返回True,我猜你的环境也是如此。 - Mark Dickinson
@MarkDickinson 对于 a=13.949999999999999,我得到的结果是 _True_。 对于 a=13.9499999,我得到的结果是 _False_。现在我有点困惑了!!! - Shashank Singh

28
我们有多种选择来做到这一点: 选项1:
x = 1.090675765757
g = float("{:.2f}".format(x))
print(g)

选项2: 内置的round()函数支持Python 2.7或更高版本。

x = 1.090675765757
g = round(x, 2)
print(g)

2
这个问题明确表示round方法不能满足他的需求。查看此答案以获取更多信息:https://dev59.com/1nRB5IYBdhLWcg3w9Lzn#455634 - Gustavo Kawamoto

24

Python教程有一个附录名为浮点算术:问题和限制。阅读它可以解释正在发生的事情并了解Python为什么尽力而为。甚至还有一个与你的例子相匹配的示例。让我引用一下:

>>> 0.1
0.10000000000000001

你可能会想使用round()函数将它截断到你期望的单个数字。但这并没有什么区别:

>>> round(0.1, 1)
0.10000000000000001
问题在于存储在"0.1"中的二进制浮点数值已经是最接近"1/10"的二进制近似值,因此尝试再次进行舍入不会使其更好:它已经是最好的了。
另一个后果是,由于"0.1"不完全等于"1/10",因此将十个"0.1"值相加可能也不会得到完全等于"1.0"的结果:
>>> sum = 0.0
>>> for i in range(10):
...     sum += 0.1
...
>>> sum
0.99999999999999989

一个解决你问题的替代方案是使用decimal模块。


15

使用Decimal对象和round()方法的组合。

Python 3.7.3
>>> from decimal import Decimal
>>> d1 = Decimal (13.949999999999999) # define a Decimal
>>> d1 
Decimal('13.949999999999999289457264239899814128875732421875')
>>> d2 = round(d1, 2) # round to 2 decimals
>>> d2
Decimal('13.95')

漂亮的图标。https://online-go.com/user/view/179 - Ray Tayek

13

针对原始 Python:

将浮点数转换为字符串并保留两位小数:

a = 13.949999999999999
format(a, '.2f')

浮点数转换为浮点数后保留2位小数:

a = 13.949999999999999
round(float(a), 2)
or
float(format(a, '.2f'))

13

它正在按照你的指示执行并且正常工作。阅读有关浮点数混乱的更多信息,或者尝试使用十进制对象。


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