2017-06-28 55 views
1

我在程序中遇到了一个错误,它正在执行重新排列方法来查找方程的根。两个不同的答案,当它们在数学上相同..?

我注意到Python根据括号产生了两个不同的答案。 例如

-4**(1/3) = -1.5874010519681994 
-4.0**(1/3) = -1.5874010519681994 
(-4)**(1/3) = (0.7937005259840999+1.3747296369986024j) 
(-4.0)**(1/3) = (0.7937005259840999+1.3747296369986024j) 

我分配到-4.0变量x,然后为x **(1/3)中,Y,但是我得到的复数而不是实际的答案。

这是为什么?有没有一种简单的方法来防止这种情况?

感谢

回答

3

您的示例中有两件事情正在进行。

首先,围绕-4的方括号很重要,因为指数运算是在操作顺序中的否定之前完成的。因此,在你的前两个例子中,权力首先完成,然后否定权力的结果。这是你所期望的,所以你没有查询这个,但是这并没有采用-4的立方根,而是立方根的负数4

第二个问题是Python中的大多数浮点运算都不准确。 1/3的结果不是分数而是浮点数。如果您使用as_integer_ratio方法上的变量存储1/3的价值,你得到的结果

(6004799503160661, 18014398509481984) 

显示,它实际上不是1比3,因此,考虑的东西的1/3力量是不一样的服用它的立方根,因为实际上不涉及这样的分数。 Python将指数解释为实际值,而不是理性值,对于负数,作为基数,x**y的值被解释为exp(y*ln(x)),正如在数学中所做的那样。负实数的对数是一个复数,所以最终结果也很复杂。

如果您实际上想要立方体根-4您可以像前两个例子那样编写计算。如果你想利用可能是负数的根一般你可以写一个程序,用定义

def power_frac(base, numerator, denominator): 
    """Return base**(numerator/denominator) where base is a 
    floating-point number and both numerator and denominator are 
    integers. 
    """ 

此功能将需要检查很多情况下,由于(例如)甚至根本否定的数字并不真实。但是这可以做到。我不相信这样的功能已经融入Python。请记住,指数必须以两个整数(或分数值)给出,因为当您将指数计算为浮点除法时,Python无法计算出您的确切分数。

如果你只是想任何实数的立方根,你可以使用

def cuberoot(x): 
    return x**(1/3) if x >= 0 else -(-x)**(1/3) 
+0

谢谢,这是比我自己的答案更详细的解释! – tzaman

+0

这与'1/3'的合理性无关。幂函数'x ** y'或者只在实数上下文中为正数'x'定义,或者在所有的x中使用您给出的公式或者在复数上下文中对其进行细化。复立方根被定义为角度最小的根,其数值结果不受'1/3'和'0.3333 ... 334'差异的影响。 – LutzL

+0

实数幂指数通常用这种方式定义:'x **(m/n)'对于'x'实数和'm'和'n'整数和'n'正数,第'n根如果存在'x ** m' - 如果实数中存在多个这样的根,请选择正根。这个问题和我的答案是基于这个共同的定义。您的定义也存在,但用于非理性指数。指数运动是少数依赖于其论证类型的实际操作之一。你否认我的定义经常被使用? –

2

这是不是一个错误,它的运算符优先级的问题。如果您检查the docs,您会看到减号运算符-的优先级低于指数运算符**。因此,你的第一个表现是:

- (4 ** (1/3)) 

,第二个是:

(-4) ** (1/3) 

这是不一样的东西都没有。

+0

好吧,但我会如何解决这个如果x = -4.0,然后我做X **(1/3 ) –

+0

不应该(-4)**(1/3)返回与第一个等式相同的值,计算器确实是 –

+0

@SylentNyte:您的计算器(例如TI-Nspire CX)几乎可以确定计算出“1/3”作为Rational类型或其他类型。和几乎所有的计算机语言一样,Python将'1/3'计算为浮点数,这不是一回事(请参阅我的答案)。 –

相关问题