如何计算浮点数的第Python个浮点数根

How to calculate Python float-number-th root of float number

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

但它只适用于整数,如第 n 个根中的 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))

参见

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

  • pow(x,y) 表示 xy
  • 提供支持
  • root(x,y) 表示 y
  • 的第 x 个根

因为这些是我们可以重写的反函数:

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

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

  • 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 roots and powers 你无法获得精确的结果。相反,您将根或幂四舍五入到最接近的可能表示形式,以尽量减少错误或使用 pow(x,y) = exp2(y*log2(x)) 方法。如果您使用任何浮点数或定点十进制数,那么您可以忘记精确的结果并从一开始就选择 pow(x,y) = exp2(y*log2(x)) ...

[注释]

我假设只有正操作数 ...如果你得到负数幂或有根那么你需要处理整数的符号根源和权力(odd/even)。因为 irational 根和幂的符号没有意义(或者至少我们还不理解)。

如果您愿意使用 Python 3.x,原生 pow() 将完全按照您的要求使用 root(x,y) = pow(x,1/y)。如果合适,它会自动 return 一个复杂的结果。

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')
>>> 

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

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

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