サーチ…


構文

  • value1 ** value2
  • pow(値1、値2 [、値3])
  • value1 .__ pow __(value2 [、value3])
  • value2 .__ rpow __(value1)
  • operator.pow(値1、値2)
  • 演算子.__ pow __(value1、value2)
  • math.pow(値1、値2)
  • math.sqrt(value1)
  • math.exp(value1)
  • cmath.exp(値1)
  • math.expm1(値1)

平方根:math.sqrt()およびcmath.sqrt

mathモジュールには、 math.sqrt() float変換できる)任意の数の平方根を計算できるmath.sqrt()関数が含まれています。結果は常にfloatます。

import math

math.sqrt(9)                # 3.0
math.sqrt(11.11)            # 3.3331666624997918
math.sqrt(Decimal('6.25'))  # 2.5

結果がcomplex場合、 math.sqrt()関数はValueError発生させます。

math.sqrt(-10)              

ValueError:数値演算ドメインエラー

math.sqrt(x)math.pow(x, 0.5)またはx ** 0.5 より高速ですが、結果の精度は同じです。 cmathモジュールは、複素数を計算することができ、その結果のすべてが+ biの形であるという点を除いて、 mathモジュールと非常に似ています。また、 .sqrt()使うこともできます:

import cmath

cmath.sqrt(4)  # 2+0j
cmath.sqrt(-4) # 2j

jとは何ですか? jは-1の平方根に相当します。すべての数は、a + biまたはこの場合はa + bjの形式に入れることができます。 a2+0jような数の実数部です。虚数部がないので、 bは0ですb2jの2のように数値の虚数部の一部を表します。これに実数部がないので、 2j0 + 2jと書くこともできます。

組み込み関数を使ったべき乗:**とpow()

指数関数は、組み込みのpow functionまたは**演算子を使用して使用できます。

2 ** 3    # 8
pow(2, 3) # 8

ほとんどの(すべてのPython 2.xの)算術演算では、結果の型はより広いオペランドの型になります。これは**は当てはまりません。次のケースはこのルールの例外です。

  • ベース: int 、指数: int < 0

    2 ** -3
    # Out: 0.125 (result is a float)
    
  • これはPython 3.xでも有効です。

  • Python 2.2.0より前は、 ValueError発生しました。

  • 基数: int < 0またはfloat < 0 、指数: float != int

    (-2) ** (0.5)  # also (-2.) ** (0.5)    
    # Out: (8.659560562354934e-17+1.4142135623730951j) (result is complex)
    
  • Python 3.0.0より前は、 ValueError発生しました。

operatorモジュールには、 ** operatorと同等の2つの関数が含まれています。

import operator
operator.pow(4, 2)      # 16
operator.__pow__(4, 3)  # 64

または__pow__メソッドを直接呼び出すことができます:

val1, val2 = 4, 2
val1.__pow__(val2)      # 16
val2.__rpow__(val1)     # 16
# in-place power operation isn't supported by immutable classes like int, float, complex:
# val1.__ipow__(val2)   

mathモジュールを使用した指数関数:math.pow()

math math.pow()は別のmath.pow()関数が含まれています。組み込みのpow() functionまたは**演算子との違いは、結果が常にfloatであることです。

import math
math.pow(2, 2)    # 4.0
math.pow(-2., 2)  # 4.0

複雑な入力を伴う計算を除外する:

math.pow(2, 2+0j) 

TypeError:complexをfloatに変換できません

複雑な結果に結びつく計算と計算:

math.pow(-2, 0.5)

ValueError:数値演算ドメインエラー

指数関数:math.exp()およびcmath.exp()

mathcmath両方のモジュールには、 Eulerの数が含まれています。eを組み込みpow() functionまたは** -operatorで使用すると、 math.exp()ように動作します。

import math

math.e ** 2  # 7.3890560989306495
math.exp(2)  # 7.38905609893065

import cmath
cmath.e ** 2 # 7.3890560989306495
cmath.exp(2) # (7.38905609893065+0j)

しかし、結果は異なります。指数関数を使用すると、基数math.e組み込み累乗よりも直接的に信頼性が高くなりmath.e

print(math.e ** 10)       # 22026.465794806703
print(math.exp(10))       # 22026.465794806718
print(cmath.exp(10).real) # 22026.465794806718
#     difference starts here ---------------^

指数関数マイナス1:math.expm1()

mathモジュールには、 expm1() math.exp(x)またはcmath.exp(x)よりも精度の低い非常に小さいxについて式math.e ** x - 1を計算できるexpm1()関数が含まれています。

import math

print(math.e ** 1e-3 - 1)  # 0.0010005001667083846
print(math.exp(1e-3) - 1)  # 0.0010005001667083846
print(math.expm1(1e-3))    # 0.0010005001667083417
#                            ------------------^

非常に小さいxの場合、差は大きくなります。

print(math.e ** 1e-15 - 1) # 1.1102230246251565e-15
print(math.exp(1e-15) - 1) # 1.1102230246251565e-15
print(math.expm1(1e-15))   # 1.0000000000000007e-15
#                              ^-------------------

この改善は、科学計算において重要である。たとえば、 プランクの法則には、指数関数から1を引いたものが含まれます。

def planks_law(lambda_, T):
    from scipy.constants import h, k, c  # If no scipy installed hardcode these!
    return 2 * h * c ** 2 / (lambda_ ** 5 * math.expm1(h * c / (lambda_ * k * T)))

def planks_law_naive(lambda_, T):
    from scipy.constants import h, k, c  # If no scipy installed hardcode these!
    return 2 * h * c ** 2 / (lambda_ ** 5 * (math.e ** (h * c / (lambda_ * k * T)) - 1))

planks_law(100, 5000)        # 4.139080074896474e-19
planks_law_naive(100, 5000)  # 4.139080073488451e-19
#                                        ^---------- 

planks_law(1000, 5000)       # 4.139080128493406e-23
planks_law_naive(1000, 5000) # 4.139080233183142e-23
#                                      ^------------

マジックメソッドと指数関数:組み込み関数、数学とcmath

純粋な整数値を格納するクラスがあるとします。

class Integer(object):
    def __init__(self, value):
        self.value = int(value) # Cast to an integer
        
    def __repr__(self):
        return '{cls}({val})'.format(cls=self.__class__.__name__,
                                     val=self.value)
    
    def __pow__(self, other, modulo=None):
        if modulo is None:
            print('Using __pow__')
            return self.__class__(self.value ** other)
        else:
            print('Using __pow__ with modulo')
            return self.__class__(pow(self.value, other, modulo))
    
    def __float__(self):
        print('Using __float__')
        return float(self.value)
    
    def __complex__(self):
        print('Using __complex__')
        return complex(self.value, 0)

組み込みのpow関数または**演算子を使用すると、常に__pow__が呼び出され__pow__

Integer(2) ** 2                 # Integer(4)
# Prints: Using __pow__
Integer(2) ** 2.5               # Integer(5)
# Prints: Using __pow__
pow(Integer(2), 0.5)            # Integer(1)
# Prints: Using __pow__  
operator.pow(Integer(2), 3)     # Integer(8)
# Prints: Using __pow__
operator.__pow__(Integer(3), 3) # Integer(27)
# Prints: Using __pow__

__pow__()メソッドの2番目の引数は、 __pow__() pow()を使うか、直接メソッドを呼び出すことによってのみ与えられます:

pow(Integer(2), 3, 4)           # Integer(0)
# Prints: Using __pow__ with modulo
Integer(2).__pow__(3, 4)        # Integer(0) 
# Prints: Using __pow__ with modulo  

math関数は常にfloat変換し、 float演算を使用します。

import math

math.pow(Integer(2), 0.5) # 1.4142135623730951
# Prints: Using __float__

cmath -functionsはそれを変換しようとcomplexだけでなく、フォールバックすることができますfloatへの明示的な変換が存在しない場合はcomplex

import cmath

cmath.exp(Integer(2))     # (7.38905609893065+0j)
# Prints: Using __complex__

del Integer.__complex__   # Deleting __complex__ method - instances cannot be cast to complex

cmath.exp(Integer(2))     # (7.38905609893065+0j)
# Prints: Using __float__

__float__()__float__()ない場合、 mathcmath__float__()ません:

del Integer.__float__  # Deleting __complex__ method

math.sqrt(Integer(2))  # also cmath.exp(Integer(2))

TypeError:浮動小数点が必要です

モジュラ累乗:3つの引数を持つpow()

pow(a, b, c) pow()を3つの引数pow() pow(a, b, c) べき乗剰余 a b mod c

pow(3, 4, 17)   # 13

# equivalent unoptimized expression:
3 ** 4 % 17     # 13

# steps:
3 ** 4          # 81
81 % 17         # 13

モジュラ累乗を使用する組み込み型の場合は、次の場合にのみ可能です。

  • 最初の引数はint
  • 2番目の引数はint >= 0
  • 3番目の引数はint != 0

これらの制限は、Python 3.xにもあります

たとえば、3つの引数をとるpowを使用して、 モジュラ逆関数を定義することができます。

def modular_inverse(x, p):
    """Find a such as  a·x ≡ 1 (mod p), assuming p is prime."""
    return pow(x, p-2, p)

[modular_inverse(x, 13) for x in range(1,13)]
# Out: [1, 7, 9, 10, 8, 11, 2, 5, 3, 4, 6, 12]

根:分数指数付きn乗根

math.sqrt関数は平方根の特定の場合に提供されますが、立方根のようなn乗根演算を実行するには、指数演算子( ** )を小数点以下の指数で使用すると便利なことがよくあります。

指数の逆数は指数の逆数による指数です。したがって、3の指数に置くことによって数値を立てることができれば、その数値を1/3の指数に置くことによって、数値の立方根を見つけることができます。

>>> x = 3
>>> y = x ** 3
>>> y
27
>>> z = y ** (1.0 / 3)
>>> z
3.0
>>> z == x
True

大きな整数のルーツを計算する

Pythonはネイティブに大きな整数をサポートしていますが、非常に大きな数値のn番目のルートを取ることはPythonでは失敗する可能性があります。

x = 2 ** 100
cube = x ** 3
root = cube ** (1.0 / 3)

OverflowError:long intが大きすぎてfloatに変換できない

そのような大きな整数を扱う場合、カスタム関数を使用して数値のn番目のルートを計算する必要があります。

def nth_root(x, n):
    # Start with some reasonable bounds around the nth root.
    upper_bound = 1
    while upper_bound ** n <= x:
        upper_bound *= 2
    lower_bound = upper_bound // 2
    # Keep searching for a better result as long as the bounds make sense.
    while lower_bound < upper_bound:
        mid = (lower_bound + upper_bound) // 2
        mid_nth = mid ** n
        if lower_bound < mid and mid_nth < x:
            lower_bound = mid
        elif upper_bound > mid and mid_nth > x:
            upper_bound = mid
        else:
            # Found perfect nth root.
            return mid
    return mid + 1

x = 2 ** 100
cube = x ** 3
root = nth_root(cube, 3)
x == root
# True


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow