简体   繁体   English

Python中的浮点概念

[英]Floating Point Concepts in Python

Why Does -22/10 return -3 in python. 为什么-22/10在python中返回-3。 Any pointers regarding this will be helpful for me. 任何关于此的指示对我都有帮助。

Because it's integer division by default. 因为它是默认的整数除法。 And integer division is rounded towards minus infinity. 并且整数除法向无穷大舍入。 Take a look: 看一看:

>>> -22/10
-3
>>> -22/10.0
-2.2000000000000002

Positive: 正:

>>> 22/10
2
>>> 22/10.0
2.2000000000000002

Regarding the seeming "inaccuracy" of floating point, this is a great article to read: Why are floating point calculations so inaccurate? 关于浮点的看似“不准确”,这是一篇很好的文章: 为什么浮点计算如此不准确?

By default, the current versions of Python 2.x (I'm not sure about 3.x) give an integer result for any arithmetic operator when both operands are integers. 默认情况下,当两个操作数都是整数时,Python 2.x的当前版本(我不确定3.x)会为任何算术运算符提供整数结果。 However, there is a way to change this behaviour. 但是,有一种方法可以改变这种行为。

from __future__ import division
print(22/10)

Outputs 输出

2.2000000000000002

Of course, a simpler way is to simply make one of the operands a float as described by the previous two answers. 当然,更简单的方法是简单地使其中一个操作数浮动,如前两个答案所述。

PEP 238 , "Changing the Division Operator", explains the issues well, I think. PEP 238 ,“改变分部操作员”,我认为这些问题很好地解释了。 In brief: when Python was designed it adopted the "truncating" meaning for / between integers, simply because most other programming languages did ever since the first FORTRAN compiler was launched in 1957 (all-uppercase language name and all;-). 简言之:当Python的设计通过了“截断”的意思为/整数之间,仅仅是因为大多数其他编程语言,因为第一个FORTRAN编译器是在1957年(全大写语言的名称和所有;-)推出有史以来做过。 (One widespread language that didn't adopt this meaning, using / to produce a floating point result and div for truncation, was Pascal). (一种广泛使用的语言没有采用这种意义,使用/生成浮点结果和div用于截断,是Pascal)。

In 2001 it was decided that this choice was not optimal (to quote the PEP, "This makes expressions expecting float or complex results error-prone when integers are not expected but possible as inputs"), and to switch to using a new operator // to request division with truncation, and change the meaning of / to produce a float result ("true division"). 在2001年,决定这个选择不是最优的(引用PEP,“这使表达式期望浮点数或复杂结果容易出现错误,当整数不被预期但可能作为输入”),并转而使用新的运算符//通过截断请求除法,并更改/的含义以产生浮点结果(“true division”)。

You can explicitly request this behavior by putting the statement 您可以通过放置语句来显式请求此行为

from __future__ import division

at the start of a module (the command-line switch -Q to the python interpreter can also control the behavior of division). 在模块的开头(命令行开关-Qpython解释器也可以控制除法的行为)。 Missing such an "import from the future" (and command line switch use), Python 2.x, for all values of x, always uses "classic division" (ie, / is truncating between int s). 对于x的所有值,缺少这样的“从未来导入”(以及命令行开关使用),Python 2.x,总是使用“经典划分”(即/int之间截断)。

Python 3, however, always uses "true division" ( / between int s produces a float ). 但是,Python 3总是使用“真正的除法”( / int之间产生一个float )。

Note a curious corollary (in Python 3)...: 请注意一个奇怪的推论(在Python 3中)......:

>>> from fractions import Fraction
>>> Fraction(1/2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/fractions.py", line 100, in __new__
    raise TypeError("argument should be a string "
TypeError: argument should be a string or a Rational instance

since / produces a float , it's not acceptable as the argument to Fraction (otherwise precision might be silently lost). 因为/产生一个float ,它不能作为Fraction的参数(否则精度可能会无声地丢失)。 You must use a string, or pass numerator and denominator as separate arguments: 您必须使用字符串,或将分子和分母作为单独的参数传递:

>>> Fraction(1, 2)
Fraction(1, 2)
>>> Fraction('1/2')
Fraction(1, 2)

gmpy uses a different, more tolerant approach to building mpq s, its equivalent of Python 3 Fraction s...: gmpy使用一种不同的,更宽容的方法来构建mpq ,相当于Python 3 Fraction ...:

>>> import gmpy
>>> gmpy.mpq(1/2)
mpq(1,2)

Specifically (see lines 3168 and following in the source ), gmpy uses a Stern-Brocot tree to get the "best practical approximation" of the floating point argument as a rational (of course, this can mask a loss of precision). 具体来说(参见第3168行和后面的源代码 ),gmpy使用Stern-Brocot树来获得浮点参数的“最佳实际近似”作为理性(当然,这可以掩盖精度的损失)。

Because you're doing an integer division. 因为你正在进行整数除法。 If you do -22.0/10 instead, you'll get the correct result. 如果你改为-22.0 / 10,你将得到正确的结果。

This happens because the operation of integer division returns the number, which when multiplied by the divisor gives the largest possible integer that is no larger than the number you divided. 发生这种情况是因为整数除法的运算返回数字,当乘以除数时,给出的最大可能整数不大于您划分的数字。

This is exactly why 22/10 gives 2: 10*2=20, which is the largest integer multiple of 10 not bigger than 20. 这正是为什么22/10给出2:10 * 2 = 20,这是10的最大整数倍且不大于20。

When this goes to the negative, your operation becomes -22/10. 当这变为负数时,您的操作变为-22/10。 Your result is -3. 你的结果是-3。 Applying the same logic as in the previous case, we see that 10*-3=-30, which is the largest integer multiple of 10 not bigger than -20. 应用与前一种情况相同的逻辑,我们看到10 * -3 = -30,这是10的最大整数倍,不大于-20。

This is why you get a slightly unexpected answer when dealing with negative numbers. 这就是为什么在处理负数时会得到一个意想不到的答案。

Hope that helps 希望有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM