【问题标题】:How to know all bases and exponents of a number?如何知道一个数的所有底数和指数?
【发布时间】:2016-11-27 10:31:52
【问题描述】:

我想找到一个数字的所有底数和指数。

例子:

Number = 64
2^6=64
4^3=64
8^2=64
64^1=64

Number = 1845.28125
4.5^5=1845.28125

Number = 19683
3^9=19683
27^3=19683
19683^1=19683

我现在要做的是制作一个整数“数字”,然后只看多次计算的结果就可以得到正确的结果:

basehits, expohits = [], []

if eval(Number) > 1000:
   to = 1000   #base max 1000 in order to avoid too many calculations
else:
   to = int(eval(Number))

for n in range(1,to):
  for s in range(1,31): #just try with exponents from 1 to 30
    calcres = pow(n,s)
    if calcres == eval(Number):
       basehits.append(n)
       expohits.append(s)
    elif calcres > eval(Number):
       break

问题是这永远不会找到浮点数,例如1845.28125(见上文)。
在只知道结果的情况下,有没有更好的方法来查找指数和底?

【问题讨论】:

  • 不要使用eval。请改用int
  • evalexec 通常应避免使用,因为它们可能存在安全风险。有关详细信息,请参阅 SO 老将 Ned Batchelder 的Eval really is dangerous

标签: python python-3.x math pow


【解决方案1】:

您的问题需要更多限制,但这里有一些帮助:

>>> from math import log
>>> help(log)
Help on built-in function log in module math:

log(...)
    log(x[, base])

    Return the logarithm of x to the given base.
    If the base not specified, returns the natural logarithm (base e) of x.

>>> for base in range(2, 10):
...     exp = log(64, base)
...     print('%s ^ %s = %s' % (base, exp, base ** exp))
...     
2 ^ 6.0 = 64.0
3 ^ 3.785578521428744 = 63.99999999999994
4 ^ 3.0 = 64.0
5 ^ 2.5840593484403582 = 63.99999999999999
6 ^ 2.3211168434072493 = 63.99999999999998
7 ^ 2.1372431226481328 = 63.999999999999964
8 ^ 2.0 = 64.0
9 ^ 1.892789260714372 = 63.99999999999994

【讨论】:

    【解决方案2】:

    怎么样

    import math    
    num=64
    for i in range(2,int(math.sqrt(num))+1):
        if math.log(num,i).is_integer():
            print i,int(math.log(num,i))
    

    输出是:

    2 6
    4 3
    8 2
    

    当然,您可以随时添加:

    print num,1 
    

    得到

    64,1
    

    如果要添加分数,点后有n个小数位,可以使用:

    from __future__ import division
    import math
    
    
    
    num=1845.28125
    decimal_digits=1
    ans=3
    x=1
    while(ans>=2):
        ans=num**(1/x)
        if (ans*10**decimal_digits).is_integer():
            print ans,x
        x+=1
    

    其中decimal_digits 表示点后的位数。

    这个例子的答案是

    4.5 5,

    如果您将 num 更改为 39.0625 并将 decimal_digits 更改为 2,则输出将为:

    2.5 4 6.25 2

    【讨论】:

    • 很好的解决方案。它仍然找不到第二个数字,但您的解决方案比我的解决方案要好得多。
    • 这是朝着正确方向迈出的一步,但它没有回答问题。
    【解决方案3】:

    整数

    对于整数,您可以查看您号码的prime factors。一旦您知道 64 是 2**6,就很容易列出您想要的所有结果。

    现在,对于具有至少 2 个不同质因数的数字,您期望得到什么结果?例如:15 应该写成3*53**1 * 5**1 还是15**1

    浮动

    不清楚您的问题是如何为浮点数定义的。

    4.5 有什么特别之处? 如果计算1845.28125**(1.0/5),Python会返回4.5,但对于其他输入数字,结果可能会相差1e-16。

    可能的解决方案

    import math
    
    def find_possible_bases(num, min_base = 1.9, max_decimals = 9, max_diff = 1e-15):
      max_exponent = int(math.ceil(math.log(num,min_base)))
      for exp in range(1,max_exponent):
        base = round(num**(1.0/exp),max_decimals)
        diff = abs(base**exp-num)
        if diff < max_diff:
          print('%.10g ** %d = %.10g' % (base, exp, base ** exp))
    
    find_possible_bases(64)
    # 64 ** 1 = 64
    # 8 ** 2 = 64
    # 4 ** 3 = 64
    # 2 ** 6 = 64
    
    find_possible_bases(19683)
    # 19683 ** 1 = 19683
    # 27 ** 3 = 19683
    # 3 ** 9 = 19683
    
    find_possible_bases(1845.28125)
    # 1845.28 ** 1 = 1845.28
    # 4.5 ** 5 = 1845.28
    
    find_possible_bases(15)
    #  15 ** 1 = 15
    

    它迭代可能的指数,并计算底数。它将它四舍五入到小数点后 9 位,并检查错误变成了什么。如果它足够小,它会显示结果。您可以使用参数并找到最适合您的问题的参数。 作为奖励,它也适用于整数(例如 64 和 15)。

    使用Rational numbers 可能会更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多