我想要 a
四舍五入到 13.95。
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
该 round
功能不按我预期的方式工作。
我想要 a
四舍五入到 13.95。
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
该 round
功能不按我预期的方式工作。
您遇到了浮点数的旧问题,无法表示所有数字。命令行只显示内存中的完整浮点形式。
在浮点数中,您的圆形版本是相同的数字。由于计算机是二进制的,它们将浮点数存储为整数,然后将其除以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("{0:.2f}".format(a))
13.95
>>> print("{0:.2f}".format(round(a,2)))
13.95
>>> print("{0:.15f}".format(round(a,2)))
13.949999999999999
如果您只有两位小数,那么您有几个更好的选择:1)使用整数并以美分存储值,而不是美元,然后除以100转换为美元。 2)或者使用固定点数 十进制。
有新的格式规范, 字符串格式规范迷你语言:
您可以这样做:
"{0:.2f}".format(13.949999999999999)
注意 以上返回一个字符串。为了得到浮动,只需用 float(...)
:
float("{0:.2f}".format(13.949999999999999))
注意 包裹着 float()
不改变任何东西:
>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{0:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
我觉得最简单的方法是使用 format()
功能。
例如:
a = 13.949999999999999
format(a, '.2f')
13.95
这会产生一个浮点数作为一个四舍五入到两个小数点的字符串。
大多数数字不能用浮点数精确表示。如果你想要对数字进行舍入,因为这是你的数学公式或算法所需要的,那么你想要使用round。如果您只想将显示限制到一定的精度,那么甚至不要使用round,只需将其格式化为该字符串即可。 (如果你想用一些替代的舍入方法显示它,并且有吨,那么你需要混合这两种方法。)
>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'
最后,尽管也许最重要的是,如果你想要的话 精确 数学,那么你根本不需要花车。通常的例子是处理货币并将“美分”存储为整数。
请尝试以下代码:
>>> a = 0.99334
>>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up
>>> print a
0.99
使用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)
但请注意,对于3以上的Python版本(例如3.2或3.3),选项2是 首选。
有关选项二的更多信息,我建议使用此链接 Python文档中的字符串格式。
有关选项一的更多信息, 这个链接就足够了,并且有关于各种标志的信息。
您可以修改输出格式:
>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95
使用
print"{:.2f}".format(a)
代替
print"{0:.2f}".format(a)
因为后者在尝试输出多个变量时可能会导致输出错误(请参阅注释)。
输入/输出的舍入问题一直存在 由Python 2.7.0解决 和 3.1 明确。
无限测试:
import random
for x in iter(random.random, None): # Verify FOREVER that rounding is fixed :-)
assert float(repr(x)) == x # Reversible repr() conversion.
assert len(repr(round(x, 10))) <= 12 # Smart decimal places in repr() after round.
if x >= 0.1: # Implicit rounding to 12 significant digits
assert str(x) == repr(round(x, 12)) # by str() is good enough for small errors.
y = 1000 * x # Decimal type is excessive for shopping
assert str(y) == repr(round(y, 12 - 3)) # in the supermaket with Python 2.7+ :-)
见 发行说明Python 2.7 - 其他语言更改 第四段:
转换 现在,浮点数和字符串之间 正确舍入 在大多数平台上。这些转换发生在许多不同的地方:浮点数上的str()和复数;浮动和复杂的构造函数;数字格式;使用。序列化和反序列化浮点数和复数
marshal
,pickle
和json
模块;在Python代码中解析float和imaginary文字;和十进制到浮点转换。与此相关, 再版() 浮点数x现在返回基于的结果 最短的十进制字符串,保证回到x 在正确的舍入下(使用舍入到半舍入到舍入模式)。以前它给出了一个基于舍入x到17十进制数字的字符串。
更多信息::格式化 float
之前Python 2.7与当前类似 numpy.float64
。两种类型都使用相同的64位 IEEE 754 双精度,52位尾数。一个很大的不同是 np.float64.__repr__
经常使用过多的十进制数格式化,以便不会丢失任何位,但13.949999999999999和13.950000000000001之间不存在有效的IEEE 754编号。结果并不好转换 repr(float(number_as_string))
是不可逆转的。另一方面: float.__repr__
格式化,以便每个数字都很重要;序列没有间隙,转换是可逆的。简单地说:如果您有一个numpy.float64数字,请将其转换为普通浮点数,以便为人类而不是数字处理器进行格式化,否则Python 2.7+不再需要它。