【问题标题】:Can someone explain this behavior with this function?有人可以用这个函数解释这种行为吗?
【发布时间】:2020-02-23 04:54:24
【问题描述】:
>>> def my_max(x,y):
        return ( x + y + abs(x - y)) / 2
>>> my_max(-894,2.3)
2.2999999999999545
>>> my_max(34,77)
77.0
>>> my_max(0.1,0.01)
0.1
>>> my_max(-0.1 , 0.01)
0.009999999999999995

我只是在玩 python,我做了这个函数,它有时可以工作,而其他的它只是靠近 awnser

我知道这与浮点错误有关,但为什么对某些输入有效而对其他输入无效??

【问题讨论】:

  • why would work for some inputs and not in others?——因为有些数字可以用浮点数精确表示,有些则不能。其中,有些是在您将它们打印到您的预期时近似的,而有些则不是。
  • 我建议尝试使用my_max(-1.0e100,1.0e10) 来了解并非所有数学公式都在浮点运算中表现良好。你明白为什么吗?

标签: python python-3.x floating-point floating-accuracy


【解决方案1】:

分离函数时更容易测试:

def m(x, y):

    first = x + y
    second = abs(x - y)
    third = first + second
    fourth = third / 2

    print("x+y\t\t\t", first)
    print("abs(x-y)\t\t", second)
    print("x+y + abs(x-y)\t\t", third)
    print("(x+y + abs(x-y))/2\t", fourth)

m(-894, 2.3)

您会收到以下输出:

x+y                  -891.7
abs(x-y)             896.3
x+y + abs(x-y)       4.599999999999909
(x+y + abs(x-y))/2   2.2999999999999545

现在查看x+y + abs(x-y),我们有以下内容:

var = -891.7 + 896.3
print(var)

哪些输出:

4.599999999999909

这当然应该是4.6,但是发生的事情可以参考Python的文档here

请注意,这是二进制浮点的本质:这不是 Python 中的错误,也不是代码中的错误。您会在所有支持硬件浮点运算的语言中看到相同的内容(尽管某些语言在默认情况下或在所有输出模式下可能不会显示差异)。

您可以利用 Python 附带的 decimal 库解决此问题:

from decimal import *

getcontext().prec = 10
var = Decimal(-891.7) + Decimal(896.3)
print(var)

输出:

4.600000000

在这种情况下,您的精度可以高达 13 以正确输出 4.6 的变体。将其增加到 14 或更大,您会注意到您将再次收到您的 4.59....

【讨论】:

    猜你喜欢
    • 2016-09-18
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多