【问题标题】:How do I write this equation in Python?如何在 Python 中编写这个方程?
【发布时间】:2016-08-12 04:37:06
【问题描述】:

我真的不知道如何正确地写这个。我就是这样尝试的:

def is_cardano_triplet(a, b, c):
    f = lambda x: x ** 1. / 2
    g = lambda x: x ** 1. / 3
    return g(a + b*f(c)) + g(a - b*f(c)) == 1

print is_cardano_triplet(2,1,5) # I should get True

我应该为2, 1, 5 获得True,但我没有。我的功能有什么问题?

【问题讨论】:

  • math.sqrtmath.pow函数,不需要自己实现。
  • 你需要重新设计你的方程以纯粹根据整数工作,或者引入一个足够强大的符号数学库。 (另外,x ** 1. / 2(x ** 1.) / 2,而不是 x ** (1. / 2)。)
  • Python 遵循 BEDMAS 并且正如 user2357112 所指出的,除非您实现括号,否则您不会将数字提高到分数幂。

标签: python python-2.7 python-2.x


【解决方案1】:

做一些计算,I found out

因此:

现在,由于 known reasons 的二进制系统上的浮点运算不精确,第一个公式很难精确计算。但是,第二个更容易计算,没有浮点精度错误,因为它不涉及无理函数,并且abc 是整数。

这是明智的解决方案:

def is_cardano_triplet(a, b, c):
    return (a + 1)**2 * (8*a - 1) - 27*b**2*c == 0

>>> is_cardano_triplet(2, 1, 5)
True

【讨论】:

  • 当然,要解决 Project Euler 问题,生成三元组并测试它们是否是 Cardano 三元组仍然是低效的,不可行。您可以尝试迭代(a + 1) / 3 的可能值(因为a 必须与2 mod 3 一致)并考虑(a + 1) / 3 的因子和(8*a - 1) / 3 的平方因子以生成有效的b 值,从中对应的c 紧随其后。
【解决方案2】:

幂运算符 (**) 的优先级高于除法一 (/)。所以你需要设置括号:

f = lambda x: x ** (1./3)

不过,浮点运算并不精确,因此您必须与一些小的不确定性进行比较:

def is_cardano_triplet(a, b, c):
    f = lambda x: x ** (1. / 2)
    g = lambda x: x ** (1. / 3)
    return abs(g(a + b*f(c)) + g(a - b*f(c)) - 1) < 1e-10

现在你明白了,负数只允许用于奇数的根,但浮点数并不精确,所以你必须手动处理负数:

def is_cardano_triplet(a, b, c):
    f = lambda x: x ** (1. / 2)
    g = lambda x: (-1 if x<0 else 1) * abs(x) ** (1. / 3)
    return abs(g(a + b*f(c)) + g(a - b*f(c)) - 1) < 1e-10

现在

print is_cardano_triplet(2,1,5)

结果为@​​987654328@。

【讨论】:

  • 虽然这是其中的一部分,但由于浮点舍入,该函数仍返回 False,请参阅 Is floating point math broken?
  • print is_cardano_triplet(2,1,5) 给我:ValueError: negative number cannot be raised to a fractional power
  • 与容差比较只会产生不同错误的结果。对于不是 Cardano 三元组的输入,您会得到误报。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 2022-07-11
相关资源
最近更新 更多