【问题标题】:How to get all the integers resulting from the expression sqrt(16+x**2) for x in [-100,100]如何获取 [-100,100] 中 x 的表达式 sqrt(16+x**2) 产生的所有整数
【发布时间】:2017-10-12 18:59:21
【问题描述】:

我想编写一个程序,它给出由表达式 y = sqrt(16 + x**2) for x in [-100,100] 产生的所有整数的列表 这个我试过了

def num():
    x= []
    for y in range (-100,100):
        z = (16+y**2)**0.5 
        if isinstance(z,int):
            x.append(z)
    return(x) 

但我遇到的问题是函数 sqrt() 总是给出一个浮点数,例如

sqrt(16+3**2)

输出[20]:5.0

【问题讨论】:

标签: python-3.x


【解决方案1】:

如果效率不是您主要关心的问题,您永远不需要处理 floats 的替代方案:

x = []
for z in range(4, 100):
    for y in range(z):
        if z**2 - y**2 == 16:
            x.append(z)

【讨论】:

  • 好皮卡!当所有值 100 相同时,从 -100 到 100 毫无意义!
【解决方案2】:

这不是你唯一的问题。

浮点数并不是所有实数的精确表示。特别是,它们不能准确地表示像平方根 2 这样的数字,我们甚至无法确定像平方根 4 这样的数字的浮点表示是否准确。

程序员至少有两种方法可以处理这个问题。

求解y 的方程。有三种解决方案,每一种都依赖于此。

我会说只有三个根。但可爱,准确的。如果您想以这种方式执行此操作,请使用 sympy 库。

一种允许浮点近似的不精确方法,适用于无法求解原始方程的情况。

tolerance 是不精确出现的地方,它是人们自己对整数和平方根例程产生的值之间愿意允许的差异的估计。请注意,必须应用 abs 运算符,以便将差值视为正值。

tolerance = 0.0001

x = []
for y in range(-100, 101):
    z = (16+y**2)**0.5
    if abs(z-round(z)) < tolerance:
        x.append(z)

print (x)

结果:

[5.0, 4.0, 5.0]

【讨论】:

  • abs(z - int(z)) &lt; tolerance 检查未通过您自己的“如果 z 是 4.999999999999999 会怎样?”测试。也许你想要abs(z - round(z))?
  • 谢谢你,@MarkDickinson!再次谦虚。
【解决方案3】:

试试模运算符:

def num():
    x= []
    for y in range (-100,100):
        z = (16+y**2)**0.5 
        if z % 1 == 0:
            x.append(z)
    return(x)

关于模的更多信息:How does % work in Python?

【讨论】:

  • 抱歉,正在用手机打字。立即尝试
  • 如果 z 是 4.999999999999999 会怎样?
【解决方案4】:

您可以使用if z==int(z),而不是if isinstance(z,int)。这将截断小数点右侧的任何内容并检查该值是否保持不变。本质上只是检查小数点右边的所有内容是否为零。

【讨论】:

  • 如果 z 是 4.999999999999999 会怎样?
【解决方案5】:

如果您愿意使用 SymPy,这个问题可以表述为丢番图方程z = sqrt(16+x**2) -&gt; z**2 = 16 + x**2,其中x 和z 必须是整数:

>>> diophantine(16 + x**2 - y**2)
{(−3,−5),(−3,5),(0,−4),(0,4),(3,−5),(3,5)}

这些是你对 x 和 y 的答案。所以在这种情况下,你的“程序”只是能够以一种可以用现有工具解决的形式来说明问题……在相对较高的层次上(与你现在工作的较低层次相比)。

【讨论】:

    【解决方案6】:

    如果只考虑从 0 到 100 的 x,则可以计算 y 值并取 int 值。这将为您提供比实际值小 1 或正确的值,因此测试两个值以查看是否满足等效关系y**2 - (16 + x**2) = 0。如果他们这样做了,那么 x 就是一个答案(-x 也是如此):

    >>> for x in range(0, 100):
    ...     arg = 16 + x**2
    ...     y1 = int(sqrt(arg))
    ...     if y1**2 == arg or (y1+1)**2 == arg:
    ...         if x == 0: print(x)
    ...         else: print(-x, x)
    0
    (-3, 3)
    

    因此,通过意识到 +/-x 给出相同的结果,您只需要搜索原始范围的一半;意识到在计算 sqrt 时您可能会偏离 1,这会使您所做的测试加倍......但对洞察力和诡计的需求要少得多。 :-)

    【讨论】:

      猜你喜欢
      • 2021-05-19
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      相关资源
      最近更新 更多