我希望a四舍五入到13.95。我尝试使用#1,但我得到:
a
>>> a13.949999999999999>>> round(a, 2)13.949999999999999
有关标准库Decimal类的类似问题,请参阅如何格式化小数以始终显示2位小数?
您遇到的老问题带有浮点数,并非所有数字都可以准确表示。命令行只是向您显示内存中的完整浮点形式。
使用浮点表示法,你的四舍五入版本是相同的数字。由于计算机是二进制的,它们将浮点数存储为整数,然后将其除以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
如果您只在小数点后两位(例如,显示货币价值),那么您有几个更好的选择:
您可以修改输出格式:
>>> a = 13.95>>> a13.949999999999999>>> print "%.2f" % a13.95
它正在做你告诉它做的事情,并且工作正常。阅读更多关于浮点混淆的信息,也许可以尝试十进制对象。
大多数数字不能精确地用浮点数表示。如果你想对数字进行四舍五入,因为这是你的数学公式或算法所需要的,那么你就需要使用圆形。如果你只想将显示限制在一定的精度,那么甚至不要使用圆形,只需将其格式化为该字符串。(如果你想用其他舍入方法显示它,并且有很多吨,那么你需要混合这两种方法。)
>>> "%.2f" % 3.14159'3.14'>>> "%.2f" % 13.9499999'13.95'
最后,也许最重要的是,如果你想要确切数学,那么你根本不需要浮点数。通常的例子是处理金钱并将“美分”存储为整数。
Python教程有一个名为浮点运算:问题和限制的附录。阅读它。它解释了正在发生的事情以及Python为什么尽力而为。它甚至有一个与您的示例相匹配的示例。让我引用一点:
>>> 0.10.10000000000000001 您可能会尝试使用round()函数将其砍回单你期望的数字。但这并不意味着差异: >>> round(0.1, 1)0.10000000000000001 问题是二进制文件为“0.1”存储的浮点值已经是最好的二进制了1/10的近似值,所以尝试再绕一次也不能让它变得更好:它已经和它一样好了。 另一个结果是,由于0.1不完全是1/10,求和100.1的值可能无法准确产生1.0或者 >>> sum = 0.0>>> for i in range(10):... sum += 0.1...>>> sum0.99999999999999989
>>> 0.10.10000000000000001
您可能会尝试使用round()函数将其砍回单你期望的数字。但这并不意味着差异:
round()
>>> round(0.1, 1)0.10000000000000001
问题是二进制文件为“0.1”存储的浮点值已经是最好的二进制了1/10的近似值,所以尝试再绕一次也不能让它变得更好:它已经和它一样好了。
“0.1”
1/10
另一个结果是,由于0.1不完全是1/10,求和100.1的值可能无法准确产生1.0或者
0.1
1.0
>>> sum = 0.0>>> for i in range(10):... sum += 0.1...>>> sum0.99999999999999989
您的问题的另一种选择和解决方案是使用#0模块。
有新的格式规范,字符串格式规范迷你语言:
你可以做同样的事情:
"{:.2f}".format(13.949999999999999)
注1:以上返回一个字符串。为了获得浮点数,只需用float(...)包装:
float(...)
float("{:.2f}".format(13.949999999999999))
注2:用float()包装不会改变任何东西:
float()
>>> x = 13.949999999999999999>>> x13.95>>> g = float("{:.2f}".format(x))>>> g13.95>>> x == gTrue>>> h = round(x, 2)>>> h13.95>>> x == hTrue
试试下面的代码:
>>> a = 0.99334>>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up>>> print a0.99
对于Python<3(例如2.6或2.7),有两种方法可以做到这一点。
# Option oneolder_method_string = "%.9f" % numvar # Option two (note ':' before the '.9f')newer_method_string = "{:.9f}".format(numvar)
但请注意,对于3以上的Python版本(例如3.2或3.3),选项二是首选。
有关选项二的更多信息,我建议在字符串格式从Python留档上提供此链接。
关于选项一的更多信息,这个链接就足够了,有关于各种旗帜的信息。
参考:将浮点数转换为一定精度,然后复制到字符串
为了在Python和JavaScript等类型动态语言中修复浮点,我使用了这种技术
# For example:a = 70000b = 0.14c = a * b print c # Prints 980.0000000002# Try to fixc = int(c * 10000)/100000print c # Prints 980
您还可以使用Decimal如下:
from decimal import *getcontext().prec = 6Decimal(1) / Decimal(7)# Results in 6 precision -> Decimal('0.142857') getcontext().prec = 28Decimal(1) / Decimal(7)# Results in 28 precision -> Decimal('0.1428571428571428571428571429')
我觉得最简单的方法是使用format()函数。
format()
例如:
a = 13.949999999999999format(a, '.2f') 13.95
这将产生一个浮点数作为四舍五入到两个小数点的字符串。
要将数字四舍五入为分辨率,最好的方法是以下方法,它可以使用任何分辨率(对于两位小数甚至其他步骤为0.01):
>>> import numpy as np>>> value = 13.949999999999999>>> resolution = 0.01>>> newValue = int(np.round(value/resolution))*resolution>>> print newValue13.95 >>> resolution = 0.5>>> newValue = int(np.round(value/resolution))*resolution>>> print newValue14.0
我使用的方法是字符串切片。它相对快速和简单。
首先,将浮点数转换为字符串,选择您想要的长度。
float = str(float)[:5]
在上面的一行中,我们将值转换为字符串,然后仅将字符串保留为其前四个数字或字符(包括)。
希望有帮助!
输入和输出的舍入问题已被最终由Python 3.1解决修复也被反向移植到Python 2.7.0。
舍入的数字可以在浮点数和字符串之间可逆转换来回:str -> float() -> repr() -> float() ...或Decimal -> float -> str -> Decimal
str -> float() -> repr() -> float() ...
Decimal -> float -> str -> Decimal
>>> 0.30.3>>> float(repr(0.3)) == 0.3True
Decimal类型不再是存储所必需的。
Decimal
算术运算的结果必须再次舍入,因为舍入错误可能会积累比解析一个数字后更多的不准确性。这并没有被改进的repr()算法修复(Python>=3.1,>=2.7.0):
repr()
>>> 0.1 + 0.20.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中也输出类似的函数。
str(float(...))
import randomfrom decimal import Decimalfor _ 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();浮点数和复数构造函数;数字格式化;使用marshal、pickle和json模块序列化和反序列化浮点数和复数;解析Python代码中的浮点数和虚数文字;以及十进制到浮点数的转换。与此相关的是,浮点数x的repr()现在在正确舍入(使用舍入半到偶数舍入模式)下返回基于保证舍入到x的最短十进制字符串的结果。以前它根据舍入x到17位十进制数字给出一个字符串。
浮点数和字符串之间的转换现在在大多数平台上是正确舍入。这些转换发生在许多不同的地方:浮点数和复数上的str();浮点数和复数构造函数;数字格式化;使用marshal、pickle和json模块序列化和反序列化浮点数和复数;解析Python代码中的浮点数和虚数文字;以及十进制到浮点数的转换。
marshal
pickle
json
与此相关的是,浮点数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+就不需要更多了。
float
numpy.float64
np.float64.__repr__
repr(float(number_as_string))
float.__repr__
内置的round()在Python 2.7或更高版本中运行良好。
示例:
>>> round(14.22222223, 2)14.22
检查留档。
使用
print"{:.2f}".format(a)
而不是
print"{0:.2f}".format(a)
因为后者在尝试输出多个变量时可能会导致输出错误(见注释)。
orig_float = 232569 / 16000.0
14.5355625
short_float = float("{:.2f}".format(orig_float))
14.54
让我举一个Python 3.6的f字串/temteme-string格式的例子,我认为它非常简洁:
>>> f'{a:.2f}'
它也适用于较长的示例,使用运算符而不需要括号:
>>> print(f'Completed in {time.time() - start:.2f}s')
作为马特指出,Python 3.6提供了f字串,他们也可以使用嵌套参数:
value = 2.34558precision = 2width = 4 print(f'result: {value:{width}.{precision}f}')
将显示result: 2.35
result: 2.35
在Python 2.7中:
a = 13.949999999999999output = float("%0.2f"%a)print output
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_strreturn 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'
它很简单,就像:
使用十进制模块进行快速正确舍入的十进制浮点运算:
d = Decimal(10000000.0000009)
实现四舍五入:
d.quantize(Decimal('0.01'))
将导致Decimal('10000000.00')
Decimal('10000000.00')
使上面的DRY:
def round_decimal(number, exponent='0.01'):decimal_value = Decimal(number)return decimal_value.quantize(Decimal(exponent))
或
def round_decimal(number, decimal_places=2):decimal_value = Decimal(number)return decimal_value.quantize(Decimal(10) ** -decimal_places)
PS:批评他人:格式不四舍五入。
您可以使用格式运算符将值四舍五入到Python中的小数点后两位:
print(format(14.4499923, '.2f')) // The output is 14.45
像这样使用lambda函数:
arred = lambda x,n : x*(10**n)//1/(10**n)
这样你就可以做:
arred(3.141591657, 2)
并获得
3.14
使用Decimal对象和round()方法的组合。
Python 3.7.3>>> from decimal import Decimal>>> d1 = Decimal (13.949999999999999) # define a Decimal>>> d1Decimal('13.949999999999999289457264239899814128875732421875')>>> d2 = round(d1, 2) # round to 2 decimals>>> d2Decimal('13.95')
lambda x, n:int(x*10^n + 0.5)/10^n
在许多语言中为我工作了许多年。
我看到的答案不适用于浮点数(52.15)情况。经过一些测试,我使用的解决方案如下:
import decimal def value_to_decimal(value, decimal_places):decimal.getcontext().rounding = decimal.ROUND_HALF_UP # define rounding methodreturn decimal.Decimal(str(float(value))).quantize(decimal.Decimal('1e-{}'.format(decimal_places)))
(将“值”转换为浮点数和字符串非常重要,这样,“值”可以是浮点数、小数、整数或字符串!)
希望这对任何人都有帮助。
我们有多种选择来做到这一点:
备选案文1:
x = 1.090675765757g = float("{:.2f}".format(x))print(g)
选项2:内置轮()支持Python 2.7或更高版本。
x = 1.090675765757g = round(x, 2)print(g)
用途:
float_number = 12.234325335563round(float_number, 2)
这将返回;
12.23
说明:
轮函数接受两个参数;要四舍五入的数字和要返回的小数位数。这里我返回了两位小数。
如果您想处理金钱,请使用Python十进制模块:
from decimal import Decimal, ROUND_HALF_UP # 'amount' can be integer, string, tuple, float, or another Decimal objectdef to_money(amount) -> Decimal:money = Decimal(amount).quantize(Decimal('.00'), rounding=ROUND_HALF_UP)return money
这是使用格式函数的简单解决方案。
float(format(num, '.2f'))
说明:我们正在将数字转换为浮点数,因为格式方法返回一个字符串。
只需使用此函数并将字节作为输入传递给它:
def getSize(bytes):kb = round(bytes/1024, 4)mb = round(kb/1024, 4)gb = round(mb/1024, 4)if(gb > 1):return str(gb) + " GB"elif(mb > 1):return str(mb) + " MB"else:return str(kb) + " KB"
这是将数据大小从字节转换为KB、MB或GB动态的最简单方法。
简单的解决办法就在这里
value = 5.34343rounded_value = round(value, 2) # 5.34
k-分子
n-分母
'%.2f'-表示您想要小数点后2位的精度
*100-将数字从小数转换为百分比
percentage = lambda k, n: '%.2f' % (k/n*100) - equivalent to- def percentage(k,n):return '%.2f' % (k/n*100)
百分比(1,3)
输出->'33.33'
为了计算,我使用一个函数来截断值也许对你有帮助
import math def truncate(number, digits) -> float:stepper = pow(10.0, digits)return math.trunc(stepper * number) / stepper print(truncate((0.1 + 0.2), 2))