Zuerst vorausgesetzt, Sie einen bestimmten Logarithmus Operator haben (viele Sprachen Logarithmen bieten 10
oder Base zu stützen e
only), logab
kann als logxb/logxa
berechnet werden (wobei x
offensichtlich eine Basis ist, die Ihre Sprache bietet).
Python geht um eins besser, da es den Logarithmus für eine beliebige Basis ohne die oben genannte knifflige Gleichheit ausarbeiten kann.
So oder so, Sie haben eine Möglichkeit, Logarithmus zu einer bestimmten Basis zu bekommen. Wenn das Protokoll b
in der Basis a
eine Ganzzahl (Anmerkung 1) ist, dann ist b
eine Leistung von a
.
Also würde ich mit dem folgenden Code starten, jetzt mit zusätzlichen Rand Fallabfragung:
# Don't even think about using this for negative powers :-)
def isPower (num, base):
if base == 1 and num != 1: return False
if base == 1 and num == 1: return True
if base == 0 and num != 1: return False
power = int (math.log (num, base) + 0.5)
return base ** power == num
zum Beispiel finden Sie in das folgende komplette Programm, das dies in Aktion zeigt:
import math
def isPower (num, base):
if base == 1 and num != 1: return False
if base == 1 and num == 1: return True
if base == 0 and num != 1: return False
power = int (math.log (num, base) + 0.5)
return base ** power == num
print isPower (127,2) # false
print isPower (128,2) # true
print isPower (129,2) # false
print
print isPower (26,3) # false
print isPower (27,3) # true
print isPower (28,3) # false
print isPower (3**10,3) # true
print isPower (3**129,3) # true
print
print isPower (5,5) # true
print isPower (1,1) # true
print isPower (10,1) # false
Wenn Sie die Sorte sind, die sich Sorgen über Fließkommaoperationen macht, können Sie mit wiederholten Multiplikationen tun, aber Sie sollten die Performa testen B. eine solche Lösung, da sie in Software wahrscheinlich wesentlich langsamer ist als in Hardware. Das wird für Dinge wie isPower(128,2)
nicht viel ausmachen, aber es könnte ein Problem für isPower(verybignum,2)
werden.
Für eine Nicht-Floating-Point-Variante des obigen Code:
def isPower (num, base):
if base == 1 and num != 1: return False
if base == 1 and num == 1: return True
if base == 0 and num != 1: return False
testnum = base
while testnum < num:
testnum = testnum * base
return testnum == num
Aber stellen Sie sicher, dass es gegen Ihre größte Zahl und kleinste Basis getestet hat man keine Performance-Schocks nicht bekommen, zu gewährleisten.
(Anmerkung 1) Beachten Sie hier die Möglichkeit, dass Punkt Unschärfen floating bedeuten kann, es ist nicht genau eine ganze Zahl. Sie müssen möglicherweise einen Vergleich "nahe genug" verwenden.
Sollten Sie nicht überprüfen, ob die math.log (n, Basis) * any * ganze Zahl ist? –
Warum wäre 'math.log (n, base)' immer gleich 'base ** n'? 128 ist eine Potenz von 2, aber '2 ** 128' ist definitiv nicht' 7'. – chrisaycock