【问题标题】:Is cube root integer?立方根是整数吗?
【发布时间】:2014-05-13 02:17:55
【问题描述】:

这似乎很简单,但我找不到方法。我需要显示整数的立方根是否为整数。我在 Python 3.4 中使用了 is_integer() float 方法,但这并不成功。作为

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

但是

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

我尝试了x%1 == 0x == int(x)isinstance(x,int),但没有成功。

如有任何意见,我将不胜感激。

【问题讨论】:

  • 不幸的是,这不是一种明智的做法。
  • @IgnacioVazquez-Abrams 好的!那么有什么理智的方法吗?
  • 并非特别如此。我会设置/找到一个上限并保留一个列表。
  • @IgnacioVazquez-Abrams 但在某种程度上它并不准确。
  • 我怀疑您的立方根遇到浮点舍入问题。如果您的值与整数相差一小部分,您会将其视为非整数。尝试使用更适合浮点数的测试:abs((x-round(x))/x) < epsilon(对于一些小的 epsilon)。

标签: python python-3.x


【解决方案1】:

对于小数(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 = 1 << ((n.bit_length() + 2) // 3)
    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

【讨论】:

  • 这看起来不错,但不幸的是我的数字比 10 美元大一点^{13}.$
  • 然后使用二分查找方式。
  • 对于二分搜索,您可以取输入的对数并使用它来计算初始lohi,以限制搜索空间。
  • abs(n) &lt; 2**n.bit_length() -> abs(n)**(1/3) &lt; 2**((n.bit_length() + 2) // 3) -> hi = 2**((n.bit_length() + 2) // 3) 例如,对于n=10**13 -> hi = 2**15 = 32768
  • 在python 3中你不需要n**(1/3.)中的点。除法总是在那里返回一个浮点数,所以你可以使用n**(1/3)
【解决方案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】:

      要详细说明@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
      

      【讨论】:

        【解决方案5】:

        这是使用math module 的另一种方法。

        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 位有效数字以说明 floating point approximations
        第 6 行:打印所选数字的第 n 个根的预览。
        第 7 行:使用 modf 函数获取小数和整数部分。
        第 8 行:打印立方根值小数部分的预览。
        第 9 行:如果立方根是整数,则返回 True。如果立方根值包含小数,则返回 False

        【讨论】:

          【解决方案6】:

          我认为您应该使用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。

          【讨论】:

            【解决方案7】:

            Python 3.11你可以使用math.cbrt

             x = 64
             math.cbrt(x).is_integer
            

            (或)

            或使用numpy.cbrt

            import numpy as np
            x = 64
            np.cbrt(x).is_integer
            

            【讨论】:

              猜你喜欢
              • 2011-05-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-09-22
              • 2014-04-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多