Извлечь корень n степени из числа k
Нужно найти функцию, позволяющую извлечь корень n-ной степени из любого числа. Грубо говоря, sqrt(27, 3) -> 3. Передали в функцию число, из которого нужно извлечь корень, передали степень корня, а она вернула извлечённый корень.
Ответы (3 шт):
def root(x, r):
if x < 0 and r==int(r):
if int(r)&1:
return -(-x)**(1/r)
if int(r)&3 == 2:
return (-x)**(1/r)*1j
return x**(1/r)
for x,r in [(27, 3), (4, 2), (-27, 3), (-4, 2), (0, 200), (-1.0, 1.0), (-1, 4)]:
y = root(x, r)
print(x, r, y, "Ok" if abs(y**r-x) < 1e-7 else "Fail!")
27 3 3.0 Ok
4 2 2.0 Ok
-27 3 -3.0 Ok
-4 2 2j Ok
0 200 0.0 Ok
-1.0 1.0 -1.0 Ok
-1 4 (0.7071067811865476+0.7071067811865475j) Ok
Корень n-й степени из числа a определяется как такое число b, что bn = a. Здесь n – натуральное число, называемое показателем или степенью корня.
Для нечётного n единственный корень существует для любого x.
Для чётного n корень определён только для неотрицательных x ≥ 0. В этом случае корней даже два, отличающихся только знаком.
Чтобы обойти все тонкости определяют арифметический корень, который применим только к неотрицательным x и всегда возвращает одно неотрицательное же значение:
def root_arith(x, n):
assert x >= 0
assert isinstance(n, int) and n >= 1
return x ** (1 / n)
Полный корень для вещественных чисел ниже. Для чётных n возвращается только положительное значение корня. Это классика:
def root_real(x, n):
assert isinstance(n, int) and n >= 1
if n % 2 != 0 and x < 0:
return -((-x) ** (1 / n))
assert x >= 0
return x ** (1 / n)
Настоящий корень вещественного числа – многозначная функция. Для нечётных n значение одно, для чётных n значений два:
def root_real(x, n):
assert isinstance(n, int) and n >= 1
if n % 2 == 0:
if x < 0:
return ()
if x == 0:
return 0,
y = x ** (1 / n)
return y, -y
if x < 0:
return -((-x) ** (1 / n)),
return x ** (1 / n),
Для комплексных чисел корень n-ой степени имеет n комплексных значений:
import cmath
def root_complex(x, n):
assert isinstance(n, int) and n >= 1
mag, phi = cmath.polar(x)
mn = mag ** (1 / n)
pn = phi / n
return tuple(cmath.rect(mn, pn + i * 2 * cmath.pi / n) for i in range(n))