Python Language
지수 계산
수색…
통사론
- 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 (값 1)
- math.exp (값 1)
- cmath.exp (값 1)
- math.expm1 (값 1)
제곱근 : math.sqrt () 및 cmath.sqrt
math
모듈은 임의의 숫자의 제곱근을 계산할 수있는 math.sqrt()
함수를 포함하며 math.sqrt()
float
으로 변환 될 수 있음) 결과는 항상 float
.
import math
math.sqrt(9) # 3.0
math.sqrt(11.11) # 3.3331666624997918
math.sqrt(Decimal('6.25')) # 2.5
math.sqrt()
함수는 결과가 complex
할 경우 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 형식으로 입력 할 수 있습니다. a
는 2의 2+0j
와 같은 숫자의 실수 부분입니다. 허수 부가 없으므로 b
는 0입니다. b
는 2j
의 2와 같이 숫자의 허수 부 부분을 나타냅니다. 이 부분에는 실제 부분이 없으므로 2j
는 0 + 2j
로 쓸 수도 있습니다.
내장 함수를 사용한 지수화 : ** 및 pow ()
지수 연산은 내장 된 pow
-function 또는 **
연산자를 사용하여 사용할 수 있습니다.
2 ** 3 # 8
pow(2, 3) # 8
대부분의 (파이썬 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와 동일한 두 개의 함수가 포함되어 있습니다.
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.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 ()
math
cmath
모듈 모두 Euler 수를 포함하고 있습니다 : e 와 그것을 builtin 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
모듈에는 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__()
메서드의 두 번째 인수는 내장 된 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-computation을 사용합니다.
import math
math.pow(Integer(2), 0.5) # 1.4142135623730951
# Prints: Using __float__
cmath
는이를 complex
로 변환하려고 시도하지만 complex
로의 명시 적 변환이없는 경우 float
폴백 할 수도 있습니다.
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__()
-method가 없으면 math
이나 cmath
도 작동하지 않습니다 :
del Integer.__float__ # Deleting __complex__ method
math.sqrt(Integer(2)) # also cmath.exp(Integer(2))
TypeError : float가 필요합니다.
모듈 형 지수화 : pow () 3 인수
공급 pow()
3 인자와 pow(a, b, c)
평가 멱승 잉여를 A B C를 개조 :
pow(3, 4, 17) # 13
# equivalent unoptimized expression:
3 ** 4 % 17 # 13
# steps:
3 ** 4 # 81
81 % 17 # 13
모듈러 지수법을 사용하는 내장 유형의 경우 다음 경우에만 가능합니다.
- 첫 번째 인수는
int
- 두 번째 인수는
int >= 0
- 세 번째 인수는
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
큰 정수 뿌리 계산하기
파이썬은 기본적으로 큰 정수를 지원하지만, 매우 큰 숫자의 n 번째 루트를 취하는 것은 파이썬에서 실패 할 수 있습니다.
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