Python ermöglicht die einfache Erstellung einer Ganzzahl aus einer Zeichenfolge einer bestimmten Basis über
int(str, base).
Ich möchte das Umgekehrte ausführen: Erstellen einer Zeichenfolge aus einer Ganzzahl , dh ich möchte eine Funktion int2base(num, base)
, z.
int(int2base(x, b), b) == x
Der Funktionsname / die Argumentreihenfolge ist unwichtig.
Für jede Zahl x
und Basis b
, int()
die akzeptiert wird.
Dies ist eine einfach zu schreibende Funktion: Tatsächlich ist es einfacher, als sie in dieser Frage zu beschreiben. Ich habe jedoch das Gefühl, dass mir etwas fehlen muss.
Ich weiß , über die Funktionen bin
, oct
, hex
, aber ich kann sie nicht für ein paar Gründe verwenden:
Diese Funktionen sind in älteren Versionen von Python nicht verfügbar, mit denen ich kompatibel sein muss mit (2.2)
Ich möchte eine allgemeine Lösung, die für verschiedene Basen gleich bezeichnet werden kann
Ich möchte andere Basen als 2, 8, 16 zulassen
Antworten:
Wenn Sie Kompatibilität mit alten Versionen von Python benötigen, können Sie entweder gmpy verwenden (das eine schnelle, vollständig allgemeine Konvertierungsfunktion für Zeichenfolgen enthält und für solche alten Versionen erstellt werden kann). Möglicherweise müssen Sie seitdem ältere Versionen ausprobieren Die jüngsten Versionen wurden nicht auf ehrwürdige Python- und GMP-Versionen getestet, sondern nur auf etwas neueren Versionen. Für weniger Geschwindigkeit, aber mehr Komfort verwenden Sie Python-Code - z. B. am einfachsten:
quelle
gmpy2.digits(x, base)
.digs = string.digits + string.lowercase + string.uppercase
string.digits + string.letters
)x //= base
was sich wie/=
in Python 2 verhält, wenn Sie die Dezimalstelle löschen . Diese Antwort sollte einen Haftungsausschluss enthalten, der für Python 2 gilt.Überraschenderweise gaben die Leute nur Lösungen an, die sich in kleine Basen umwandeln lassen (kleiner als die Länge des englischen Alphabets). Es gab keinen Versuch, eine Lösung zu finden, die sich in eine beliebige Base von 2 bis unendlich umwandelt.
Also hier ist eine super einfache Lösung:
Wenn Sie also eine super große Zahl in die Basis konvertieren müssen
577
,numberToBase(67854 ** 15 - 102, 577)
, gibt Ihnen eine korrekte Lösung :[4, 473, 131, 96, 431, 285, 524, 486, 28, 23, 16, 82, 292, 538, 149, 25, 41, 483, 100, 517, 131, 28, 0, 435, 197, 264, 455]
,Was Sie später in eine beliebige Basis konvertieren können
quelle
int(4545,16)
gab "11c1" undint(4545,60)
gab "1:15:45". Somit hatte die Funktion eine dreifache Aufgabe: Konvertieren in Dezimal-, Computer- und Zeitstempelformate.digits
?Ref: http://code.activestate.com/recipes/65212/
Bitte beachten Sie, dass dies dazu führen kann
für sehr große ganze Zahlen.
quelle
len(numerals)
ist und (b)num % b
glücklicherweise <istlen(numerals)
. Obwohl dienumerals
Zeichenfolge nur 36 Zeichen lang ist, gibt baseN (60, 40) zurück,'1k'
während baseN (79, 40) ein erhöhtIndexError
. Beide sollten einen Fehler auslösen. Der Code sollte überarbeitet werden, um einen Fehler auszulösen, wennnot 2 <= base <= len(numerals)
.b
dies nichtlen(numerals)
viel Glück für Sie bedeuten würde.return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]
ist genauso kurz.quelle
0
ist unnötig. Hier ist die Python 2-Dokumentation: docs.python.org/2/library/string.html#format-string-syntaxhex(100)[2:]
,oct(100)[2:]
undbin(100)[2:]
.Tolle Antworten! Ich denke, die Antwort auf meine Frage war "nein". Mir fehlte keine offensichtliche Lösung. Hier ist die Funktion, die ich verwenden werde, um die guten Ideen, die in den Antworten zum Ausdruck kommen, zu verdichten.
quelle
Rekursiv
Ich würde die am häufigsten gewählte Antwort auf Folgendes vereinfachen :
Mit dem gleichen Rat für
RuntimeError: maximum recursion depth exceeded in cmp
sehr große ganze Zahlen und negative Zahlen. (Sie könnten verwendensys.setrecursionlimit(new_limit)
)Iterativ
So vermeiden Sie Rekursionsprobleme :
quelle
return BS[0] if not n
? Nur für den Fall, dass Sie ausgefallene Ziffern verwenden möchten, wie ich :)return BS[n] if n < b else to_base(n // b) + BN[n % b]
Python verfügt nicht über eine integrierte Funktion zum Drucken einer Ganzzahl in einer beliebigen Basis. Sie müssen Ihre eigenen schreiben, wenn Sie wollen.
quelle
Sie können
baseconv.py
aus meinem Projekt verwenden: https://github.com/semente/python-baseconvBeispielnutzung:
Es gibt einige bultin Wandler wie zum Beispiel
baseconv.base2
,baseconv.base16
undbaseconv.base64
.quelle
>>> numpy.base_repr(10, base=3) '101'
quelle
clac
wegen Bedenken hinsichtlich der Ladezeit einzumischen . Das Vorladen von numpy verdreifacht die Laufzeit der einfachen Expressionsbewertung in clac um mehr als das Dreifache: z. B.clac 1+1
ging es von etwa 40 ms auf 140 ms.numpy.base_repr()
die Basis ein Limit von 36 hat. Ansonsten wirft es aValueError
http://code.activestate.com/recipes/65212/
Hier ist noch einer vom selben Link
quelle
Ich habe ein Pip-Paket dafür gemacht.
Ich empfehle Ihnen, meine base.py https://github.com/kamijoutouma/bases.py zu verwenden, die von base.js inspiriert wurde
Informationen zu den verwendbaren Basen finden Sie unter https://github.com/kamijoutouma/bases.py#known-basesalphabets
BEARBEITEN: pip link https://pypi.python.org/pypi/bases.py/0.2.2
quelle
Ausgabe:
quelle
other-base
ist das gleiche wieother - base
, also sollten Sie verwendenother_base
decimal
Null ist.quelle
Eine rekursive Lösung für Interessierte. Dies funktioniert natürlich nicht mit negativen Binärwerten. Sie müssten Two's Complement implementieren.
quelle
Erläuterung
In jeder Basis ist jede Zahl gleich
a1+a2*base**2+a3*base**3...
Die "Mission" ist es, alle a zu finden.Für jeden
N=1,2,3...
isoliert der Code dasaN*base**N
durch "Mouduling" durch b, fürb=base**(N+1)
das alle a größer als N sind, und schneidet alle a, deren Seriennummer kleiner als N ist, durch Verringern von a jedes Mal, wenn die Funktion vom Strom aufgerufen wirdaN*base**N
.Basis% (Basis-1) == 1 dafür Basis ** p% (Basis-1) == 1 und dafür q * Basis ^ p% (Basis-1) == q mit nur einer Ausnahme, wenn q = Basis-1 Dies gibt 0 zurück. Um dies zu beheben, falls es 0 zurückgibt, prüft die Funktion von Anfang an, ob es 0 ist.
Vorteile
In dieser Stichprobe gibt es nur eine Multiplikation (anstelle einer Division) und einige Moudulues, was relativ wenig Zeit in Anspruch nimmt.
quelle
quelle
quelle
Hier ist ein Beispiel, wie eine Zahl einer beliebigen Basis in eine andere Basis konvertiert wird.
quelle
quelle
Noch eine kurze (und imo leichter zu verstehen):
Und mit der richtigen Ausnahmebehandlung:
quelle
Eine andere Lösung, die mit Basis 2 bis 10 arbeitet, muss für höhere Basen geändert werden:
Beispiel:
quelle
Hier ist eine rekursive Version, die vorzeichenbehaftete Ganzzahlen und benutzerdefinierte Ziffern verarbeitet.
quelle
Zeichenfolgen sind nicht die einzige Wahl für die Darstellung von Zahlen: Sie können eine Liste von Ganzzahlen verwenden, um die Reihenfolge jeder Ziffer darzustellen. Diese können leicht in eine Zeichenfolge konvertiert werden.
Keine der Antworten lehnt Basis <2 ab; und die meisten laufen sehr langsam oder stürzen bei sehr großen Zahlen mit Stapelüberläufen ab (z. B. 56789 ** 43210). Um solche Fehler zu vermeiden, reduzieren Sie diese schnell wie folgt:
Speedwise
n_to_base
ist vergleichbar mitstr
großen Zahlen (ca. 0,3 s auf meinem Computer), aber wenn Sie es mit anderen vergleichen, werdenhex
Sie überrascht sein (ca. 0,3 ms auf meinem Computer oder 1000x schneller). Der Grund ist, dass die große Ganzzahl im Speicher in der Basis 256 (Bytes) gespeichert ist. Jedes Byte kann einfach in eine zweistellige Hex-Zeichenfolge konvertiert werden. Diese Ausrichtung erfolgt nur für Basen mit Zweierpotenzen, weshalb es Sonderfälle für 2,8 und 16 gibt (und base64, ascii, utf16, utf32).Betrachten Sie die letzte Ziffer einer Dezimalzeichenfolge. In welcher Beziehung steht es zu der Folge von Bytes, die seine ganze Zahl bilden? Lassen Sie uns beschriften Sie die Bytes
s[i]
mits[0]
ist das am wenigsten signifikante (Little Endian). Dann ist die letzte Ziffersum([s[i]*(256**i) % 10 for i in range(n)])
. Nun, es kommt vor, dass 256 ** i mit einer 6 für i> 0 endet (6 * 6 = 36), so dass die letzte Ziffer ist(s[0]*5 + sum(s)*6)%10
. Daraus können Sie ersehen, dass die letzte Ziffer von der Summe aller Bytes abhängt. Diese nichtlokale Eigenschaft erschwert die Konvertierung in Dezimalzahlen.quelle
quelle
Nun, ich persönlich benutze diese von mir geschriebene Funktion
So können Sie es verwenden
print(to_base(7, base=2))
Ausgabe:
"111"
print(to_base(23, base=3))
Ausgabe:
"212"
Bitte zögern Sie nicht, Verbesserungen in meinem Code vorzuschlagen.
quelle
quelle
Dies ist eine alte Frage, aber ich dachte, ich würde meine Meinung dazu teilen, da ich der Meinung bin, dass es etwas einfacher ist als andere Antworten (gut für Basen von 2 bis 36):
quelle
Ich habe hier keine Schwimmerkonverter gesehen. Und ich habe die Gruppierung immer dreistellig verpasst.
MACHEN:
-Zahlen im wissenschaftlichen Ausdruck
(n.nnnnnn*10**(exp)
- das'10'
istself.baseDigits[1::-1]/self.to_string(len (self.baseDigits))
-from_string-Funktion.
-Basis 1 -> römische Zahlen?
-repr von Komplex mit Agles
Also hier ist meine Lösung:
quelle
Ausgabe:
In eine beliebige Basis umzuwandeln, ist auch invers einfach.
quelle
NameError: global name 'n' is not defined
. Solldivmod(x, n)
seindivmod(x, b)
?