如何计算浮点数的Python float-number-th根

时间:2015-12-11 10:48:53

标签: python math gmpy nth-root

我在Stackoverflow上找到了以下答案:

https://stackoverflow.com/a/356187/1829329

但它仅适用于第n个根中的整数:

import gmpy2 as gmpy

result = gmpy.root((1/0.213), 31.5).real
print('result:', result)

结果:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-eb4628226deb> in <module>()
      8 
----> 9 result = gmpy.root((1/0.213), 31.5).real
     10 
     11 print('result:', result)

TypeError: root() requires 'mpfr','int' arguments

计算这样一个根的好方法是什么? (这是某些公式的python代码表示,我需要在演讲中用它来计算。)

修改#1

以下是我的解决方案,该解决方案基于Spektre的答案以及来自here at http://math.stackexchange.com的人员提供的信息。

import numpy as np

def naive_root(nth, a, datatype=np.float128):
    """This function can only calculate the nth root, if the operand a is positive."""
    logarithm = np.log2(a, dtype=datatype)
    exponent = np.multiply(np.divide(1, nth, dtype=datatype), logarithm, dtype=datatype)
    result = np.exp2(exponent, dtype=datatype)
    return result

def nth_root(nth, a, datatype=np.float128):
    if a == 0:
        print('operand is zero')
        return 0
    elif a > 0:
        print('a > 0')
        return naive_root(nth, a, datatype=datatype)
    elif a < 0:
        if a % 2 == 1:
            print('a is odd')
            return -naive_root(nth, np.abs(a))
        else:
            print('a is even')
            return naive_root(nth, np.abs(a))

3 个答案:

答案 0 :(得分:1)

请参阅Power by squaring for negative exponents

无论如何,因为我不在python或gmpy中编码,所以首先要定义一些定义:

  • pow(x,y)表示由x
  • 提供支持的y
  • root(x,y)表示x - y
  • 的根

由于这些是反函数,我们可以重写:

  • pow(root(x,y),x)=y

equation

您可以使用它来检查是否正确。由于函数是反向的,你也可以这样写:

  • pow(x,1/y)=root(y,x)
  • root(1/x,y)=pow(y,x)

因此,如果您获得了分数(理性)根或幂,您可以将其计算为具有反函数的整数对应物。

此外,如果您有类似root(2/3,5)之类的内容,那么您需要先将整数操作数分开:

root(2/3,5)=pow(root(2,5),3)
 ~11.18034 = ~2.236068   ^3
 ~11.18034 = ~11.18034

对于 irational 根和权力,您无法获得准确的结果。相反,您可以将根或电源绕到最近的可能表示,以最小化错误或使用pow(x,y) = exp2(y*log2(x))方法。如果你使用任何浮点数或定点十进制数,那么你可以忘记精确的结果,并从一开始就去pow(x,y) = exp2(y*log2(x)) ...

<强> [注释]

我假设只有正操作数 ...如果你有负数驱动或根那么你需要处理整数根和幂的符号(奇数/偶数) 。对于理性根源和权力的标志没有意义(或者至少我们还不了解)。

答案 1 :(得分:1)

如果您愿意使用Python 3.x,只需使用pow(),原生root(x,y) = pow(x,1/y)即可完全按照您的要求执行操作。如果合适,它将自动返回复杂的结果。

Python 3.4.3 (default, Sep 27 2015, 20:37:11)
[GCC 5.2.1 20150922] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> pow(1/0.213, 1/31.5)
1.0503191465568489
>>> pow(1/0.213, -1/31.5)
0.952091565004975
>>> pow(-1/0.213, -1/31.5)
(0.9473604081457588-0.09479770688958634j)
>>> pow(-1/0.213, 1/31.5)
(1.045099874779588+0.10457801566102139j)
>>>

返回复杂的结果而不是引发ValueError是Python 3中的一项更改。如果您希望Python 2具有相同的行为,则可以使用gmpy2并启用复杂的结果。

>>> import gmpy2
>>> gmpy2.version()
'2.0.5'
>>> gmpy2.get_context().allow_complex=True
>>> pow(1/gmpy2.mpfr("0.213"), 1/gmpy2.mpfr("31.5"))
mpfr('1.0503191465568489')
>>> pow(-1/gmpy2.mpfr("0.213"), 1/gmpy2.mpfr("31.5"))
mpc('1.0450998747795881+0.1045780156610214j')
>>> pow(-1/gmpy2.mpfr("0.213"), -1/gmpy2.mpfr("31.5"))
mpc('0.94736040814575884-0.094797706889586358j')
>>> pow(1/gmpy2.mpfr("0.213"), -1/gmpy2.mpfr("31.5"))
mpfr('0.95209156500497505')
>>> 

答案 2 :(得分:0)

这是我使用的东西似乎适用于任何数字就好了:

root = number**(1/nthroot)
print(root)

它适用于任何数字数据类型。