Является ли целое число кубов?

Это кажется простым, но я не могу найти способ сделать это. Мне нужно показать, является ли корень куба целого целым или нет. Я использовал метод is_integer() float в Python 3.4, но это не удалось. Как

x = (3**3)**(1/3.0) 
is_integer(x)    
True

но

x = (4**3)**(1/3.0) 
is_integer(x)    
False

Я пробовал x%1 == 0, x == int(x) и isinstance(x,int) без успеха.

Буду признателен за любые комментарии.

Ответ 1

Для небольших чисел (< ~ 10 13 или так) вы можете использовать следующий подход:

def is_perfect_cube(n):
    c = int(n**(1/3.))
    return (c**3 == n) or ((c+1)**3 == n)

Это усекает кубирование с плавающей запятой, затем проверяет два ближайших целых числа.

Для больших чисел один из способов сделать это - выполнить двоичный поиск истинного корня куба с использованием целых чисел только для сохранения точности:

def find_cube_root(n):
    lo = 0
    hi = n
    while lo < hi:
        mid = (lo+hi)//2
        if mid**3 < n:
            lo = mid+1
        else:
            hi = mid
    return lo

def is_perfect_cube(n):
    return find_cube_root(n)**3 == n

Ответ 2

В SymPy есть также функция integer_nthroot, которая быстро найдет целочисленный n-й корень из числа и скажет вам, было ли это также и то, что:

>>> integer_nthroot(primorial(12)+1,3)
(19505, False)

Таким образом, ваша функция может быть

def is_perfect_cube(x): return integer_nthroot(x, 3)[1]

(И поскольку SymPy является открытым исходным кодом, вы можете посмотреть процедуру, чтобы увидеть, как работает integer_nthroot.)

Ответ 3

Если ваши цифры невелики, я бы сделал:

def is_perfect_cube(number):
    return number in [x**3 for x in range(15)]

Конечно, 15 можно заменить чем-то более подходящим.

Если вам нужно иметь дело с большими числами, я бы использовал библиотеку sympy, чтобы получить более точные результаты.

from sympy import S, Rational

def is_perfect_cube(number):
    # change the number into a sympy object
    num = S(number)
    return (num**Rational(1,3)).is_Integer

Ответ 4

Я думаю, что вы должны использовать функцию round чтобы получить ответ. Если бы мне пришлось написать функцию, то это будет выглядеть следующим образом:

def cube_integer(n):
    if round(n**(1.0/3.0))**3 == n:
        return True
    return False

Вы можете использовать что-то похожее на int(n**(1.0/3.0)) == n**(1.0/3.0), но в python из-за некоторых проблем с вычислением значения корня куба это вычисляется не совсем точно, Например, int(41063625**(1.0/3.0)) даст вам 344, но значение должно быть 345.

Ответ 5

Чтобы подробнее ответить на @nneonneo, можно было написать более общую функцию kth-root для использования вместо cube_root,

def kth_root(n,k):
    lb,ub = 0,n #lower bound, upper bound
    while lb < ub:
        guess = (lb+ub)//2
        if pow(guess,k) < n: lb = guess+1
        else: ub = guess
    return lb

def is_perfect_cube(n):
    return kth_root(n,3) == n

Ответ 6

Это еще один подход с использованием математического модуля.

import math
num = int(input('Enter a number: '))
root = int(input('Enter a root: '))
nth_root = math.pow(num, (1/root))
nth_root = round(nth_root, 10)
print('\nThe {} root of {} is {}.'.format(root, num, nth_root))
decimal, whole = math.modf(nth_root)
print('The decimal portion of this cube root is {}.'.format(decimal))
decimal == 0

Строка 1: Импорт математического модуля.
Строка 2: введите число, от которого вы хотите получить корень.
Строка 3: введите n-ный корень, который вы ищете.
Строка 4: Используйте функцию питания.
Строка 5: округлено до 10 значащих цифр для учета приближений с плавающей запятой.
Строка 6: распечатать предварительный просмотр n-го корня выбранного номера.
Строка 7: используйте функцию modf, чтобы получить дробные и целочисленные части.
Строка 8: печать предварительного просмотра десятичной части корневого значения куба.
Строка 9: вернуть True, если корень куба является целым числом. Вернуть False, если значение корня куба содержит дробные числа.