我希望a四舍五入到13.95。我试过用圆形,但我得到:
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
有关标准库Decimal类的类似问题,请参阅How can I format a Decimal to always show 2 Decimal places?。
我希望a四舍五入到13.95。我试过用圆形,但我得到:
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
有关标准库Decimal类的类似问题,请参阅How can I format a Decimal to always show 2 Decimal places?。
当前回答
使用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')
其他回答
TLDR;)
Python 3.1已经明确解决了输入和输出的舍入问题,该修复程序也被移植到Python 2.7.0。
舍入数字可以在浮点数和字符串之间来回转换:str->float()->repr()->float)。。。或Decimal->float->str->Decimal
>>> 0.3
0.3
>>> float(repr(0.3)) == 0.3
True
存储不再需要十进制类型。
算术运算的结果必须再次舍入,因为舍入误差可能累积的误差比解析一个数字后可能累积的更大。这不是通过改进的repr()算法解决的(Python>=3.1,>=2.7.0):
>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1, 0.2, 0.3
(0.1, 0.2, 0.3)
在Python<2.7x和<3.1中,输出字符串函数str(float(…))被舍入为12个有效数字,以防止类似于未固定repr()输出的无效数字过多。在减去非常相似的数字之后,这仍然是不够的,并且在其他操作之后,它被舍入得太多。Python 2.7和3.1使用相同长度的str(),尽管repr()是固定的。一些旧版本的Numpy也有过多的无效数字,即使是固定的Python。当前Numpy是固定的。Python版本>=3.2中str()和repr()函数的结果相同,Numpy中也有类似函数的输出。
Test
import random
from decimal import Decimal
for _ in range(1000000):
x = random.random()
assert x == float(repr(x)) == float(Decimal(repr(x))) # Reversible repr()
assert str(x) == repr(x)
assert len(repr(round(x, 12))) <= 14 # no excessive decimal places.
文档
请参阅发行说明Python 2.7-其他语言更改第四段:
在大多数平台上,浮点数和字符串之间的转换现在都可以正确舍入。这些转换发生在许多不同的地方:浮点和复数上的str();浮点和复杂的构造函数;数字格式;使用marshall、pickle和json模块对浮点数和复数进行序列化和反序列化;Python代码中浮点和虚文本的解析;以及十进制到浮点转换。与此相关,浮点数x的repr()现在返回一个基于最短十进制字符串的结果,该字符串保证在正确舍入(使用舍入半到偶数模式)下舍入回x。之前它给出了一个基于将x舍入到17位小数的字符串。
相关问题
更多信息:Python 2.7之前的float格式类似于当前的numpy.float64。两种类型使用相同的64位IEEE 754双精度和52位尾数。一个很大的区别是np.fat64.__repr_经常使用过量的十进制数字进行格式化,因此不会丢失任何位,但在13.949999999999999和13.95000000000001之间不存在有效的IEEE 754数字。结果不好,转换repr(float(number_as_string))不能用numpy可逆。另一方面:浮动__repr_的格式使得每个数字都很重要;序列是无间隙的,并且转换是可逆的。简单地说:如果您可能有一个numpy.float64数字,请将其转换为普通浮点,以便为人类而不是数字处理器格式化,否则Python 2.7+就不需要更多了。
from decimal import Decimal
def round_float(v, ndigits=2, rt_str=False):
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)
结果:
Python 3.6.1 (default, Dec 11 2018, 17:41:10)
>>> round_float(3.1415926)
Decimal('3.14')
>>> round_float(3.1445926)
Decimal('3.14')
>>> round_float(3.1455926)
Decimal('3.15')
>>> round_float(3.1455926, rt_str=True)
'3.15'
>>> str(round_float(3.1455926))
'3.15'
orig_float = 232569 / 16000.0
14.5355625
short_float = float("{:.2f}".format(orig_float))
14.54
你遇到了一个关于浮点数的老问题,不是所有的数字都能精确表示。命令行只是显示内存中的完整浮点形式。
对于浮点表示法,舍入版本是相同的数字。由于计算机是二进制的,它们将浮点数存储为整数,然后将其除以2的幂,因此13.95将以类似于125650429603636838/(2**53)的方式表示。
双精度数字的精度为53位(16位),常规浮点数的精度为24位(8位)。Python中的浮点类型使用双精度来存储值。
例如
>>> 125650429603636838/(2**53)
13.949999999999999
>>> 234042163/(2**24)
13.949999988079071
>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999
如果您只在小数点后两位(例如显示货币值),那么您有两个更好的选择:
使用整数并以美分而非美元存储值,然后除以100转换为美元。或者使用小数等固定点数。
这很简单,比如:
使用十进制模块进行快速正确舍入的十进制浮点运算:d=十进制(10000000.0000009)为了实现舍入:d.quantite(十进制('0.01'))将产生十进制('10000000.00')使上述干燥:def round_decimal(数字,指数='0.01'):decimal_value=十进制(数字)return decimal_value.g量化(十进制(指数))或定义round_decimal(数字,小数位数=2):decimal_value=十进制(数字)return decimal_value.g量化(十进制(10)**-decimal_places)
PS:对其他人的批评:格式不是舍入。