如何将 -1 / (-343)^(1/3) 计算为 Python 中的 1/7?
How to compute -1 / (-343)^(1/3) as 1/7 in Python?
我喜欢将 Python 纳入我对功能的探索中,但是我遇到了这些评估中我没有预料到或不想要的行为。
>>> def h(x):
... return -1 / x**(1/3)
...
>>> h(-343)
(-0.07142857142857145 + 0.12371791482634838j)
我想要以下函数的真反函数:
>>> def f(x):
... return x**3
...
>>> f(-7)
-343
这样:
>>> def h(x):
... return -1/inverse_f(x)
...
>>> h(-343)
0.14285714285714285
是否有 Pythonic 方法来实现此行为?
如果您只想在 整数 中工作(并忽略函数的复杂解决方案),这可能是一种方法。至少对于标题中的示例,它可以满足您的要求。 (所以这只解决了你的问题的标题;因为其余部分现在已经改变了,所以它不会帮助...... Nayuki's answer 会)
gmpy2
有一个 iroot
方法:
import gmpy2
print(gmpy2.iroot(343, 3)) # -> (mpz(7), True)
从那里开始,您应该能够组合您的功能。
import gmpy2
from fractions import Fraction
def h(x):
sign = 1 if x >= 0 else -1
root, is_int = gmpy2.iroot(abs(x), 3)
if not is_int:
return None # the result is not an integer
root = int(root)
return -sign * Fraction(1, root)
print(h(-343)) # -> 1/7
反之:
def g(x):
return -Fraction(1, x**3)
print(g(h(-343))) # -> -343
你遇到了问题,因为负数的分数次幂可以是 complex number。
解决方案是应用数学恒等式。我们知道如果x是负数,那么x1/3等于-((- x)1/3)。也就是说,我们把x变成一个正数,取立方根,再取反。这是执行此操作的 Python 代码:
def h(x):
if x >= 0:
return -1.0 / x**(1.0/3.0)
else: # x < 0
return -h(-x)
为了首先解释您遇到问题的原因,查看 x**y
(幂运算符)的实现会有所帮助。关键的数学恒等式是 xy = exp(log(x) · y).这个恒等式使得处理幂更容易,因为指数被视为一个常规数字,不需要分析(它是整数吗?是分数吗?是负数吗?等等)。
当x为正数时,log(x)为实数。只要 y 也是实数,exp(log(x) · y) 就会是一个实数。
但当x为负数时,log(x)为复数。具体来说,它等于 [log(-x) + π · i]。当我们将这样一个复数乘以 y 然后应用 exp() 时,结果通常是一个复数 - 这不是您所希望的。
我喜欢将 Python 纳入我对功能的探索中,但是我遇到了这些评估中我没有预料到或不想要的行为。
>>> def h(x):
... return -1 / x**(1/3)
...
>>> h(-343)
(-0.07142857142857145 + 0.12371791482634838j)
我想要以下函数的真反函数:
>>> def f(x):
... return x**3
...
>>> f(-7)
-343
这样:
>>> def h(x):
... return -1/inverse_f(x)
...
>>> h(-343)
0.14285714285714285
是否有 Pythonic 方法来实现此行为?
如果您只想在 整数 中工作(并忽略函数的复杂解决方案),这可能是一种方法。至少对于标题中的示例,它可以满足您的要求。 (所以这只解决了你的问题的标题;因为其余部分现在已经改变了,所以它不会帮助...... Nayuki's answer 会)
gmpy2
有一个 iroot
方法:
import gmpy2
print(gmpy2.iroot(343, 3)) # -> (mpz(7), True)
从那里开始,您应该能够组合您的功能。
import gmpy2
from fractions import Fraction
def h(x):
sign = 1 if x >= 0 else -1
root, is_int = gmpy2.iroot(abs(x), 3)
if not is_int:
return None # the result is not an integer
root = int(root)
return -sign * Fraction(1, root)
print(h(-343)) # -> 1/7
反之:
def g(x):
return -Fraction(1, x**3)
print(g(h(-343))) # -> -343
你遇到了问题,因为负数的分数次幂可以是 complex number。
解决方案是应用数学恒等式。我们知道如果x是负数,那么x1/3等于-((- x)1/3)。也就是说,我们把x变成一个正数,取立方根,再取反。这是执行此操作的 Python 代码:
def h(x):
if x >= 0:
return -1.0 / x**(1.0/3.0)
else: # x < 0
return -h(-x)
为了首先解释您遇到问题的原因,查看 x**y
(幂运算符)的实现会有所帮助。关键的数学恒等式是 xy = exp(log(x) · y).这个恒等式使得处理幂更容易,因为指数被视为一个常规数字,不需要分析(它是整数吗?是分数吗?是负数吗?等等)。
当x为正数时,log(x)为实数。只要 y 也是实数,exp(log(x) · y) 就会是一个实数。
但当x为负数时,log(x)为复数。具体来说,它等于 [log(-x) + π · i]。当我们将这样一个复数乘以 y 然后应用 exp() 时,结果通常是一个复数 - 这不是您所希望的。