代码之家  ›  专栏  ›  技术社区  ›  Chaitanya

Python中的浮点概念

  •  3
  • Chaitanya  · 技术社区  · 16 年前

    为什么-22/10在python中返回-3。任何关于这方面的建议都会对我有所帮助。

    5 回复  |  直到 16 年前
        1
  •  5
  •   Alex Martelli    16 年前

    PEP 238 “更改除法运算符”,我认为这很好地解释了问题。简而言之:在设计Python时,它采用了 / / 要生成浮点结果,请执行以下操作: div 对于截断,为Pascal)。

    2001年,决定该选择不是最佳选择(引用PEP,“这使得期望浮点或复杂结果的表达式在不期望整数但可能作为输入时容易出错”),并切换到使用新运算符 // 请求用截断除法,并更改 / 生成浮点结果(“真除法”)。

    您可以通过放置语句来显式请求此行为

    from __future__ import division
    

    在模块的开头(命令行开关 -Q python 解释器还可以控制除法的行为)。由于缺少这种“从未来导入”(以及命令行开关的使用),Python2.x对于x的所有值始终使用“经典除法”(即。, / 是在 int s) 。

    然而,Python3总是使用“真正的除法”( / 之间 int s产生一个 float ).

    请注意一个奇怪的推论(在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
    

    自从 / 产生 浮动 ,这是不可接受的 Fraction (否则,精度可能会自动丢失)。必须使用字符串或传递分子和分母作为单独的参数:

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

    gmpy 使用不同的、更宽容的方法来构建 mpq s、 它相当于Python3 分数

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

    具体而言(请参见中的第3168行和后续内容 the source ),gmpy使用 Stern-Brocot tree 要获得浮点参数作为有理数的“最佳实用近似”(当然,这是 可以 掩盖精度损失)。

        2
  •  10
  •   Eli Bendersky    16 年前

    因为默认情况下它是整数除法。整数除法被四舍五入到负无穷大。看一看:

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

    肯定的:

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

    关于看似“不准确”的浮点,这是一篇值得阅读的好文章: Why are floating point calculations so inaccurate?

        3
  •  5
  •   Chinmay Kanchi    16 年前

    默认情况下,当前版本的Python2.x(我不确定是否为3.x)在两个操作数都是整数时为任何算术运算符提供整数结果。然而,有一种方法可以改变这种行为。

    from __future__ import division
    print(22/10)
    

    输出

    2.2000000000000002
    

        4
  •  2
  •   Can Berk Güder Pugalmuni    16 年前

    因为你在做整数除法。如果改为-22.0/10,则会得到正确的结果。

        5
  •  2
  •   inspectorG4dget Dillon Benson    16 年前

    这是因为整数除法运算返回的是一个数字,当该数字与除数相乘时,得到的可能的最大整数不大于所除数。

    这就是为什么22/10给出2:10*2=20,这是10的最大整数倍,不大于20。

    当这变成负数时,运算变成-22/10。结果是-3。应用与前一个例子相同的逻辑,我们看到10*-3=-30,这是10的最大整数倍,不大于-20。

    这就是为什么在处理负数时会得到一个稍微出乎意料的答案。

    希望有帮助