Python - 将浮点数保留两位小数

3
我需要将一个浮点变量四舍五入保留两位有效数字并将结果存储到一个新变量中(或者是之前的同一变量,都可以),但是会发生以下情况:
>>> a    
981.32000000000005    
>>> b= round(a,2)    
>>> b
981.32000000000005

我需要这个结果,但需要将它存储为一个浮点数变量,而不是字符串……
>>> print b    
981.32

实际上,截断(truncate)也可以使用,我在这种情况下不需要极高的精度。


3
你确定吗?我无法重现你演示的问题。 - karthikr
为什么不能是字符串?稍后再将其转换为浮点数即可。 - aIKid
@karthikr 或许是不同的处理器? - aIKid
1
可能是重复的问题:Python 如何将浮点数限制在两位小数 - roippi
3
这个值在2.7.5版本上是完全相同的,只是在打印输出这个值时进行了某些特殊处理。 - David Heffernan
显示剩余3条评论
4个回答

10

你试图做的实际上是不可能的。这是因为 981.32 无法准确地表示为二进制浮点数值。最接近双精度二进制浮点数值是:链接.

981.3200000000000500222085975110530853271484375

我怀疑这可能会让你有些震惊。如果是这样,那么我建议你阅读《计算机科学家应该了解的浮点数算术知识》

你可以选择以下其中一种方式来解决你的问题:

  1. 接受二进制浮点数无法精确表示此类值,并继续使用它们。不进行任何舍入,保留完整的值。当你希望将值显示为文本时,请将其格式化为仅包含两位小数。
  2. 使用可以精确表示数字的数据类型。这意味着使用十进制而非二进制类型。在Python中,你可以使用decimal

1
怎么不可能呢? - Padraic Cunningham
2
@PadraicCunningham 我做不到。你也做不到。没有人能做到。在二进制浮点数中是不可能的。这是不可能的。 - David Heffernan
@user3484521,你应该使用decimal包来代替float - TheSoundDefense
2
@user3484521,您在机器上看到的“工作”是数字的简化显示,而不是其实际内容。 - cmd
浮点数的形式为k/2^n,其中kn是整数。如果k/2^n等于981.32,那么kn的哪个值是这样的? - David Heffernan
显示剩余10条评论

1

Try this :

Round = lambda x, n: eval('"%.' + str(int(n)) + 'f" % ' + repr(x))

print Round(0.1, 2)
0.10
print Round(0.1, 4)
0.1000
print Round(981,32000000000005, 2)
981,32

只需在第二个kwarg参数中指定您想要的数字位数即可。


1
我写了这个问题的解决方案。请尝试。
from decimal import *
from autorounddecimal.core import adround,decimal_round_digit


decimal_round_digit(Decimal("981.32000000000005")) #=> Decimal("981.32")
adround(981.32000000000005) # just wrap decimal_round_digit

更多细节可以在https://github.com/niitsuma/autorounddecimal中找到。


0

Python打印浮点数和存储浮点数的方式是不同的。例如:

>>> a = 1.0/5.0
>>> a
0.20000000000000001
>>> print a
0.2

正如David Heffernan所指出的那样,许多浮点数的确无法存储精确表示。如果将浮点数看作分数,分母是2的幂(例如1/4、3/8、5/64),则可以实现。否则,由于二进制的固有限制,只能使用近似值。

Python意识到了这一点,当您使用print函数时,它会使用上面看到的更好的表示形式。这可能会让您认为Python正在完全存储浮点数,但实际上并非如此,因为IEEE标准浮点表示法无法实现。计算中的差异相当微不足道,因此对于大多数实际目的而言,这不是问题。但是,如果您真的需要这些有效数字,请使用decimal包。


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