繁体   English   中英

如果稍后再添加print(),Python将为我提供不同的输出

[英]Python gives me different outputs if I add a print() later on

我对编程非常陌生,只想做一些事情来找到方程x^3 - 1 = xx的近似值。 我知道-2大于0-1小于。 我的想法是,如果我找到平均值并检查它是否大于或小于0 ,则可以重新定义ab并重复直到得到一个近似值。 不过,我一直很难使它正确执行。 例如,如果我在没有print(i)的情况下运行此块,我将得到-1.5 ,这是平均值,但是当我将print(total)放到函数equation(n)以查看其是否正常工作时,它会甚至没有告诉我,仅输出-8.881784197001252e-16 如果我将print(i)放在if/else可能性的末尾,例如这样,它将打印16 ,然后-8.881784197001252e-16 我正在使用PyCharm CE。

除了这个小故障,我的逻辑是否正确? 通过将占位符设置为1 ,它将运行while循环。 while循环将获取新的n值并运行该函数,将其与0进行比较,然后根据该比较重新分配ab 提前致谢。

a = float(-2)
b = float(-1)
n = ((a+b)/2)
print(n)

def equation(n):

    total = float((n - n**3 - 1))

    return total

i = 1

while i != 0:
    n = ((a + b) / 2)
    if (equation(n)) > 0.0:
        a = n
        i = equation(n)
        print(i)

    else:
        b = n
        i = equation(n)
        print(i)

将所有方程x^3 - 1 = x移到一侧应使x^3 - 1 - x = 0x - x^3 + 1 = 0 您的函数中有其他方程式。

另一个问题是x=-2x=-1之间的两个方程之间没有交集(请参阅此处 )。 您需要先将窗口扩展到x=2然后才能看到交集。

一些经常发生的数值分析(在那里你会看到这种类型的问题)是不是试图找到x ,实际上使方程给出0 ,我们寻找的值x产生以下错误的可接受的水平。 另一种方法是测试while b - a > tol:

如果我们使用所有这些来调整您所拥有的,您将拥有

a = float(-2)
b = float(2)
tol = 0.001

def equation(n):
    return float(n - n**3 + 1)

n = (a + b) / 2
iter = 0
while abs(equation(n) - 0) > tol and iter < 100:
    iter+=1

    if equation(n) > 0.0:
        a = n
    else:
        b = n

    n = (a + b) / 2

    print(iter,a,b,equation(n))

注意:如果您移除浮子,然后这样做,就可以正常工作

a = -2
b = 2
#...etc

因为python已经根据需要重铸了值。 尝试

>>> type(3)
<class 'int'>
>>> type(3.5)
<class 'float'>
>>> type(float(3))
<class 'float'>
>>> type(3/5)
<class 'float'>

因此python将在必要时立即将结果存储为浮点数。

当前的问题是浮子精度有限。 如果在一百次迭代后打印ab ,则会得到:

a, b = -1.324717957244746, -1.3247179572447458
print((a + b) / 2  # -1.3247179572447458, the same as b

因此,在某些时候,b永远不会改变,这就是为什么会出现无限循环的原因。 如果我们以ab的平均值评估equation ,您将得到-8.881784197001252e-16,这是您一直看到的值。

但是,这绝不会收敛到恰好为零,因为该解决方案是不合理的 ,所以即使你有无限的精度,方程永远不会等于零。

解决此问题的常用方法是避免比较浮点数:

if a == b               # don't do this
if abs(a - b) < epsilon      # do this, where epsilon is some small value

(注意:您要描述的是二分法 ,它比高阶算法(例如牛顿法)要慢,您可以使用它,因为可以获得导数)

暂无
暂无

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

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