答案 0 :(得分:1377)
您遇到了浮点数的旧问题,无法表示所有数字。命令行只显示内存中的完整浮点形式。
在浮点数中,您的圆形版本是相同的数字。由于计算机是二进制的,它们将浮点数存储为整数,然后除以2的幂,因此13.95将以与125650429603636838 /(2 ** 53)类似的方式表示。
双精度数字具有53位(16位)的精度,而常规浮点数具有24位(8位)的精度。用于存储值的floating point in Python uses double precision。
例如,
>>> 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)或使用固定点数,如decimal。
答案 1 :(得分:495)
有新格式规范,String Format Specification Mini-Language:
您可以这样做:
"{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
答案 2 :(得分:227)
内置的round()
在Python 2.7或更高版本中运行良好。
示例:
>>> round(14.22222223, 2)
14.22
查看http://jumptuck.com/2009/01/09/wordpress-on-non-standard-port-not-port-80/。
答案 3 :(得分:131)
我觉得最简单的方法是使用format()
函数。
例如:
a = 13.949999999999999
format(a, '.2f')
13.95
这会产生一个浮点数作为一个四舍五入到两个小数点的字符串。
答案 4 :(得分:89)
大多数数字无法在浮点数中准确表示。如果你想要对数字进行舍入,因为这是你的数学公式或算法所需要的,那么你想要使用round。如果您只想将显示限制到一定的精度,那么甚至不要使用round,只需将其格式化为该字符串即可。 (如果你想用一些替代的舍入方法显示它,并且有吨,那么你需要混合这两种方法。)
>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'
最后,虽然也许最重要的是,如果您想要完全数学,那么您根本不需要浮点数。通常的例子是处理货币并将“美分”存储为整数。
答案 5 :(得分:79)
使用
print"{:.2f}".format(a)
而不是
print"{0:.2f}".format(a)
因为后者在尝试输出多个变量时可能会导致输出错误(请参阅注释)。
答案 6 :(得分:69)
尝试以下代码:
>>> a = 0.99334
>>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up
>>> print a
0.99
答案 7 :(得分:51)
使用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为preferred。
有关选项二的更多信息,我建议string formatting from the Python documentation上的此链接。
有关选项一的更多信息,this link will suffice and has information on the various flags。
参考: Convert floating point number to a certain precision, and then copy to string
答案 8 :(得分:44)
您可以修改输出格式:
>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95
答案 9 :(得分:39)
输入/输出的舍入问题已经明确地通过Python 2.7.0 和 3.1 解决。
正确舍入的数字可以来回可逆转换:
str -> float() -> repr() -> float() ...
或Decimal -> float -> str -> Decimal
存储不再需要十进制类型。
(当然,可能需要对舍入数字的加法或减法结果进行舍入,以消除累积的最后一位错误。显式十进制算法仍然很方便,但是str()
转换为字符串(如果不需要极端精度或不需要极端数量的连续算术运算,则通常使用舍入到12个有效数字就足够了。)
无限期测试:
import random
from decimal import Decimal
for x in iter(random.random, None): # Verify FOREVER that rounding is fixed :-)
assert float(repr(x)) == x # Reversible repr() conversion.
assert float(Decimal(repr(x))) == x
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 a supermaket with Python 2.7+ :-)
参见Release notes Python 2.7 - Other Language Changes第四段:
在大多数平台上,浮点数和字符串之间的转化次数现在正确舍入。这些转换发生在许多不同的地方:浮点数上的str()和复数;浮动和复杂的构造函数;数字格式;使用
marshal
,pickle
和json
模块序列化和反序列化浮点数和复数;在Python代码中解析float和imaginary文字;和十进制到浮点数转换。与此相关,浮点数x的 repr()现在返回基于最短的十进制字符串的结果,该字符串保证回滚到x 下正确的舍入(使用舍入到舍入舍入模式)。以前它给出了一个基于x到17十进制数字的字符串。
更多信息:Python 2.7之前float
的格式与当前numpy.float64
类似。两种类型都使用相同的64位IEEE 754双精度和52位尾数。一个很大的区别是np.float64.__repr__
经常格式化为十进制数过多,因此不会丢失任何位,但13.949999999999999和13.950000000000001之间不存在有效的IEEE 754号。结果不太好,转换repr(float(number_as_string))
与numpy不可逆。另一方面:float.__repr__
的格式是每个数字都很重要;序列没有间隙,转换是可逆的。简单地说:如果您可能有一个numpy.float64数字,请将其转换为普通浮点数,以便为人类而不是数字处理器进行格式化,否则Python 2.7 +不再需要它。
答案 10 :(得分:27)
在Python 2.7中:
a = 13.949999999999999
output = float("%0.2f"%a)
print output
答案 11 :(得分:24)
这里似乎没有人提到它,所以让我举一个Python 3.6的f-string / template-string格式的例子,我觉得它非常整洁:
>>> f'{a:.2f}'
对于更长的例子,它也适用于运算符而不需要parens:
>>> print(f'Completed in {time.time() - start:.2f}s')
答案 12 :(得分:20)
Python教程有一个名为 Floating Point Arithmetic: Issues and Limitations 的附录。阅读。它解释了发生了什么以及为什么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
模块。
答案 13 :(得分:16)
您可以使用 format 运算符在python中将值四舍五入至小数点后两位:
print(format(14.4499923, '.2f')) // output is 14.45
答案 14 :(得分:12)
它正在完成你告诉它要做的事情并且正常工作。阅读有关floating point confusion的更多信息,并尝试使用decimal个对象。
答案 15 :(得分:11)
正如@Matt所指出的那样, Python 3.6提供了f-strings ,他们也可以使用 nested parameters :
value = 2.34558
precision = 2
width = 4
print(f'result: {value:{width}.{precision}f}')
将显示result: 2.35
答案 16 :(得分:7)
为了修复类型动态语言(如Python和JavaScript)中的浮点,我使用了这种技术
# For example:
a = 70000
b = 0.14
c = a * b
print c # Prints 980.0000000002
# Try to fix
c = int(c * 10000)/100000
print c # Prints 980
您还可以使用Decimal:
from decimal import *
getcontext().prec = 6
Decimal(1) / Decimal(7)
# Results in 6 precision -> Decimal('0.142857')
getcontext().prec = 28
Decimal(1) / Decimal(7)
# Results in 28 precision -> Decimal('0.1428571428571428571428571429')
答案 17 :(得分:7)
我们有多种选择可以做到这一点: 选项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)
答案 18 :(得分:6)
orig_float = 232569 / 16000.0
14.5355625
short_float = float("{:.2f}".format(orig_float))
14.54
答案 19 :(得分:6)
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'
答案 20 :(得分:4)
float_number = 12.234325335563
round(float_number, 2)
这将返回;
12.23
round函数有两个参数; 要四舍五入的数字和要返回的小数位数。在这里,我返回了2个小数位数。
答案 21 :(得分:3)
就像1,2,3这样简单:
使用decimal模块进行快速正确舍入的十进制浮点运算:
d =十进制(10000000.0000009)
实现舍入:
d.quantize(Decimal('0.01'))
将产生Decimal('10000000.00')
def round_decimal(number, exponent='0.01'):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(exponent))
OR
def round_decimal(number, decimal_places=2):
decimal_value = Decimal(number)
return decimal_value.quantize(Decimal(10) ** -decimal_places)
PS:对他人的批评:格式不是四舍五入。
答案 22 :(得分:2)
像这样的lambda函数呢?
arred = lambda x,n : x*(10**n)//1/(10**n)
这样您就可以做到:
arred(3.141591657,2)
并获得
3.14
答案 23 :(得分:2)
我看到的答案不适用于float(52.15)情况。经过一些测试,有我正在使用的解决方案:
import decimal
def value_to_decimal(value, decimal_places):
decimal.getcontext().rounding = decimal.ROUND_HALF_UP # define rounding method
return decimal.Decimal(str(float(value))).quantize(decimal.Decimal('1e-{}'.format(decimal_places)))
(“值”到浮点数然后是字符串的转换非常重要,这样,“值”可以是浮点,小数,整数或字符串类型!)
希望这对任何人都有帮助。
答案 24 :(得分:0)
结合使用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')
答案 25 :(得分:0)
lambda x,n:int(x * 10 n + .5)/ 10 n在许多语言中为我工作了很多年。
答案 26 :(得分:0)
如果您想赚钱,请使用python decimal模块
from decimal import Decimal, ROUND_HALF_UP
# amount can be integer, string, tuple, float, or another Decimal object
def to_money(amount) -> Decimal:
money = Decimal(amount).quantize(Decimal('.00'), rounding=ROUND_HALF_UP)
return money
答案 27 :(得分:0)
这是使用格式函数的简单解决方案。
float(format(num, '.2f'))
<块引用>
注意:我们正在将数字转换为浮点数,因为格式方法是 返回字符串。
答案 28 :(得分:-13)
我使用的方法是字符串切片。它相对快速而简单。
首先,将float转换为字符串,选择你想要的长度。
float = str(float)[:5]
在上面的单行中,我们已将值转换为字符串,然后将字符串仅保留为前四位数或字符(包括)。
希望有所帮助!