【问题标题】:Logical thinking for a Calculation of Square root计算平方根的逻辑思维
【发布时间】:2013-07-17 00:36:17
【问题描述】:

在过去的一个小时里,我一直在尝试破解这个问题,但在这里遇到了一些麻烦。这就是问题

这种计算数字 n 平方根的方法开始于 对平方根进行(非零)猜测。然后它使用 原来的猜测计算新的猜测,根据公式

newGuess = ((n / oldGuess) + oldGuess) / 2.0;

有两个变量oldGuessnewGuess。将oldGuess初始化为 n / 2.0 并根据上述公式计算 newGuess。采用 一个while循环迭代,只要绝对值 oldGuessnewGuess 之间的差异大于 1.0E-06。不要忘记将oldGuess 的值重置为 newGuess while 循环中的值。

在您的程序中,您将提示用户输入一个正数。 如果该数字为负数,则打印一条错误消息并要求用户 再试一次。对于正数,使用 以上方法。找出你得到的平方根之间的差 以及使用幂运算符获得的值。写 输出用户输入的值、您计算的平方根以及 差异(你的平方根 - n ** 0.5

这是我目前的程序

def main():
    n = eval(input("Enter a positive number: "))
    while (n <= 0):
        print ("Error please re-input")
        n = eval(input("Enter a positive number: "))
     
    oldGuess = n / 2.0
    newGuess = ((n / oldGuess) + oldGuess) / 2.0;
    difference = n - n ** 0.5      
    while (difference < 1 * 10 ** -6):
        print ("Error")
        difference = abs(n - n ** 0.5)
    print ("Difference:", difference)

main()

所以我真的不明白我们如何告诉程序进行猜测然后计算变量 n 的平方根。我什至不认为我的 while 语句在这种情况下是正确的。我不使用已经嵌入到 python 中的 squareroot 函数,所以它必须手动完成我相信仍然迷失了guess 函数的含义。

【问题讨论】:

  • 这是一道作业题吗?
  • 您希望在绝对差异大于而不是很小的情况下继续迭代。
  • 使用eval 是危险的。请改用float
  • 如果你想实现一个平方根算法,n ** 0.5 真的不属于这里。
  • 如果你不确定你的循环在做什么,要么添加 print 调用来显示你,要么使用 interactive visualizer,内置调试器,你最喜欢的 IDE 的图形包装器调试器等并找出答案。这比猜测或尝试推理要容易得多。

标签: python python-3.3 square-root


【解决方案1】:
while True:
    n = float(input("Enter a positive number: "))
    if n > 0:
        break
    print ("Error please re-input")

oldGuess = n / 2.0
while True:
    newGuess = ((n / oldGuess) + oldGuess) / 2.0;
    oldGuess = newGuess
    if -1e-6 < n - newGuess * newGuess < 1e-6:
        break

print ("Difference:", abs(n ** .5 - newGuess))

【讨论】:

  • @user2357112,您应该将 -1 保存为错误答案。关于作业的 SO 政策非常明确。此外,当我发布此内容时,并没有提及家庭作业。
  • @gnibbler 很明显这是作业,但你是对的。
  • 所以我不知道中断的确切含义。我在这里尝试遵循您的逻辑。我仍然不明白为什么我们需要 oldGuess = newGuess?我们不能只做一个 if 语句,比如 if newGuess - oldGuess = 1 e-6 然后什么都不返回:打印差异?
  • @SulimanSharif,break 是为了避免在进入循环之前需要初始化newGuess
  • @SulimanSharif:你不不想什么都不返回。你想不断做出越来越好的猜测,直到你足够接近,然后返回你最好的猜测。如果您不更新oldGuess,您将继续使用您的第一个猜测并继续重新计算您的第二个猜测。
【解决方案2】:

将那些eval()s 更改为float()s。 eval() 会执行它交给的任何代码,这意味着您的用户可能会在那里输入恶意内容。

现在,将其用于第二部分:

oldGuess = n / 2.0
newGuess = ((n / oldGuess) + oldGuess) / 2.0
while (abs(oldGuess - newGuess) > 1e-06):
    oldGuess, newGuess = newGuess, ((n / oldGuess) + oldGuess) / 2.0
print("Guess: " + str(n))
print("My root: " + str(newGuess))
print("Accuracy: " + str(newGuess - (n**0.5)))

逗号语法是一种 Python 习惯用法,可用于无需执行任何操作即可交换值:

temp = new
new = old * something
old = temp

当您的差异小于 比那个(非常小的)值时,您的 while 循环条件正在寻找结束循环。因此,只要它大于,你就会循环。

注意:您也可以使用math.sqrt(n) 代替n ** 0.5。你必须import math

如果您想查看您的程序在做什么,请尝试在while 循环中使用print 输入oldGuessnewGuess 的值。在您得出答案之前,您会看到它正在改变它们。

编辑

我注意到您似乎对为什么必须这样做oldGuess = newGuess 感到困惑。让我解释一下:= 运算符与数学中的等号不同。等号表示左边的东西和右边的东西是一样的;即它们是等价的。在 Python 中,= 运算符表示“给左边的东西和右边的东西相同的值”。它被称为 assignment 运算符。您正在考虑 == 运算符,它(基本上)测试等效性。

>>> a = 10
>>> b = 4
>>> b = a
>>> b
10
>>> a == b
True
>>> c = 6
>>> b = c
>>> b
6
>>> a == b
False
>>> b == c
True
>>> a == c
False
>>> a,b,c
(10, 6, 6)

如您所见,当您使用= 运算符时,您并没有将变量“链接”在一起,而是说它们现在是同一个东西。如果您设置b = a,然后设置b = cb == a 将变为假,因为b 不再具有与a 相同的值。 a 也不会改变,因为 b 被赋予了它的值,而不是相反。想想看起来像 &lt;-= 运算符(我认为某些语言实际上使用它作为赋值运算符)。

为什么这很重要?好吧,你确实为变量分配了一些新的东西,你忘记了旧的值。除非您有另一个变量存储相同的值,否则它会永远丢失。您的任务说将oldGuess 更新为以前的newGuess。换句话说,如果您的猜测是“a”、“b”、“c”、“d”,那么您将从 oldGuess 作为“a”开始,然后从那里计算 newGuess 作为“b”。由于这显然不是正确的猜测,所以您说 oldGuess 现在就是 newGuess 的样子 - “b”,然后您计算下一个 newGuess,即“c”。

您需要oldGuess 的值来计算newGuess 的值。但是,您需要newGuess 的值(在您更改它之前)来更新oldGuess 的值。这是一个 catch-22,除非您存储 newGuess 的先前值,如我上面所示(作为交换示例)。这就是你需要这个的原因。

【讨论】:

  • 感谢您的帮助。绝对需要对此进行澄清
【解决方案3】:

所以我想通了,谢谢大家的帮助。我不知道我们不能在这里发布家庭作业问题,但我正在努力学习如何编码,这样我才能做得更好。这是我的最终解决方案。

def main():

    n = float(input("Enter a positive number: "))
    while (n <= 0):
     print ("Error please re-input")
     n = eval(input("Enter a positive number: "))

    oldGuess = n / 2.0
    newGuess = 0

    difference = 10
    while (difference >= 1 * 10 ** -6):
     newGuess = ((n / oldGuess) + oldGuess) / 2.0
     difference = abs(newGuess - oldGuess)
     oldGuess = newGuess

    print ("Square Root is: ", newGuess)


    differenceSqrt = newGuess - n ** 0.5
    print ("Difference is: ", differenceSqrt)



main()

我仍然不知道如何有效地使用中断,所以感谢 gnibbler 但不能真正遵循您的代码。 (新手,抱歉)

【讨论】:

  • 我敢肯定,只要您的问题不符合these categories 的任何一项,您就可以询问家庭作业。 (因此,让您的问题不那么具体到您的作业,而是更笼统,以便对其他人有用......例如,您可以将此问题命名为“平方根计算中的循环问题”或类似的东西。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 2017-04-30
  • 1970-01-01
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多