我希望a四舍五入到13.95。我试过用圆形,但我得到:

>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999

有关标准库Decimal类的类似问题,请参阅How can I format a Decimal to always show 2 Decimal places?。


你遇到了一个关于浮点数的老问题,不是所有的数字都能精确表示。命令行只是显示内存中的完整浮点形式。

对于浮点表示法,舍入版本是相同的数字。由于计算机是二进制的,它们将浮点数存储为整数,然后将其除以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转换为美元。或者使用小数等固定点数。


您可以修改输出格式:

>>> a = 13.95
>>> a
13.949999999999999
>>> print "%.2f" % a
13.95

它正按照您的指示执行,并且工作正常。阅读更多关于浮点混淆的内容,并尝试使用十进制对象。


大多数数字不能用浮点数精确表示。如果你想舍入这个数字,因为这是你的数学公式或算法所要求的,那么你想使用舍入。如果您只想将显示限制为某一精度,那么甚至不要使用舍入,只需将其格式化为字符串即可。(如果您想用其他舍入方法显示,并且有吨,则需要混合使用这两种方法。)

>>> "%.2f" % 3.14159
'3.14'
>>> "%.2f" % 13.9499999
'13.95'

最后,也许最重要的是,如果你想要精确的数学,那么你根本不需要浮点数。通常的例子是处理货币,并将“美分”存储为整数。


Python教程有一个名为“浮点算术:问题和限制”的附录。阅读它。它解释了正在发生的事情以及为什么Python做得最好。它甚至有一个与您的示例相匹配的示例。让我引用一点:

>>> 0.10.10000000000000001您可能会尝试使用round()函数将其切回单个您期望的数字。但这并不意味着差异:>>>圆形(0.1,1)0.10000000000000001问题是二进制文件为“0.1”存储的浮点值已经是最好的二进制了接近1/10,因此尝试再圆一次也不能让它变得更好:它已经很好了。另一个结果是,由于0.1不是十分之一,加十0.1的值可能不会产生精确的结果1.0,或者:>>>总和=0.0>>>对于范围(10)中的i:…总和+=0.1...>>>总和0.99999999999999989

解决问题的另一种方法是使用十进制模块。


有新的格式规范,字符串格式规范迷你语言:

您可以执行以下操作:

"{:.2f}".format(13.949999999999999)

注1:上面返回一个字符串。为了获得float,只需用float(…)包装:

float("{:.2f}".format(13.949999999999999))

注意2:用float()换行不会改变任何内容:

>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True

请尝试以下代码:

>>> 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文档中的字符串格式链接。

关于选项一的更多信息,这个链接就足够了,并提供了各种标志的信息。

引用:将浮点数转换为特定精度,然后复制为字符串


为了修复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')

我觉得最简单的方法是使用format()函数。

例如:

a = 13.949999999999999
format(a, '.2f')

13.95

这将产生一个浮点数,作为四舍五入到两个小数点的字符串。


要将一个数字舍入为一个分辨率,最好的方法是以下方法,该方法可以适用于任何分辨率(两个小数或甚至其他步长为0.01):

>>> import numpy as np
>>> value = 13.949999999999999
>>> resolution = 0.01
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
13.95

>>> resolution = 0.5
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
14.0

我使用的方法是字符串切片。它相对快速和简单。

首先,将浮点数转换为字符串,然后选择您希望的长度。

float = str(float)[:5]

在上面的单行中,我们将值转换为字符串,然后将字符串仅保留为其前四位数字或字符(包括)。

希望这有帮助!


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+就不需要更多了。


内置round()在Python 2.7或更高版本中运行良好。

例子:

>>> round(14.22222223, 2)
14.22

查看文档。


Use

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-string/模板字符串格式的例子,我认为它非常整洁:

>>> f'{a:.2f}'

它也适用于较长的示例,使用运算符,不需要括号:

>>> print(f'Completed in {time.time() - start:.2f}s')

正如Matt所指出的,Python 3.6提供了f字符串,它们也可以使用嵌套参数:

value = 2.34558
precision = 2
width = 4

print(f'result: {value:{width}.{precision}f}')

显示结果:2.35


在Python 2.7中:

a = 13.949999999999999
output = 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_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'

这很简单,比如:

使用十进制模块进行快速正确舍入的十进制浮点运算: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:对其他人的批评:格式不是舍入。


在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
>>> d1 
Decimal('13.949999999999999289457264239899814128875732421875')
>>> d2 = round(d1, 2) # round to 2 decimals
>>> d2
Decimal('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 method
    return decimal.Decimal(str(float(value))).quantize(decimal.Decimal('1e-{}'.format(decimal_places)))

(将“value”转换为float和string非常重要,这样一来,“value”可以是float、decimal、integer或string类型!)

希望这对任何人都有帮助。


我们有多种选择:

选项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)

Use:

float_number = 12.234325335563
round(float_number, 2)

这将返回;

12.23

说明:

round函数接受两个参数;要舍入的数字和要返回的小数位数。这里我返回了两位小数。


如果您想处理金钱,请使用Python十进制模块:

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

下面是使用format函数的简单解决方案。

float(format(num, '.2f'))

注意:我们将数字转换为浮点数,因为format方法返回字符串。


只需使用此函数并将字节作为输入传递给它:

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.34343
rounded_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))

对于原始Python:

对于浮点到字符串转换的2个小数点:

a = 13.949999999999999
format(a, '.2f')

对于浮点到浮点转换的2个小数点:

a = 13.949999999999999
round(float(a), 2)
or
float(format(a, '.2f'))