2010-08-24 11 views
6

Ich brauche eine Basiskonverterfunktion für Lua. Ich muss von Basis 10 auf Basis 2,3,4,5,6,7,8,9,10,11 ... 36 konvertieren, wie kann ich dazu?Lua Basiskonverter

+1

Es erscheint ein wenig merkwürdig, dass die Basen 2 bis 36 in der Richtung Text zur Nummer verfügbar sind, aber nicht umgekehrt. – RBerteig

+1

Ich zähle die :) Thue Morse-Sequenz – Woland

Antwort

13

in der (ein Array zum Beispiel usign) string zu number Richtung, die Funktion tonumber() ein optionales zweites Argument, das die Basis spezifiziert, zu verwenden, die 2 bis 36 mit der offensichtlichen Bedeutung für die Ziffern in Basen größer als 10

in der Anzahl zu bespannen Richtung reichen kann, Dies kann etwas effizienter als Nikolaus's answer durch etwas getan werden:

 

local floor,insert = math.floor, table.insert 
function basen(n,b) 
    n = floor(n) 
    if not b or b == 10 then return tostring(n) end 
    local digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    local t = {} 
    local sign = "" 
    if n < 0 then 
     sign = "-" 
    n = -n 
    end 
    repeat 
     local d = (n % b) + 1 
     n = floor(n/b) 
     insert(t, 1, digits:sub(d,d)) 
    until n == 0 
    return sign .. table.concat(t,"") 
end 

Dadurch werden weniger Garbage-Strings zum Sammeln erstellt, indem table.concat() anstelle von wiederholten Aufrufen des Zeichenfolgenverkettungsoperators .. verwendet wird. Obwohl es für kleine Strings wenig praktischen Unterschied macht, sollte dieses Idiom erlernt werden, da ansonsten das Erstellen eines Puffers in einer Schleife mit dem Verkettungsoperator tatsächlich zu einer Leistung führt, während table.concat() wesentlich besser ausgeführt wurde.

Dort ist eine offene Frage ist, ob es effizienter ist, die Ziffern auf einem Stapel in der Tabelle t mit Aufrufen an table.insert(t,1,digit), oder zu hängen Sie sie an das Ende mit t[#t+1]=digit zu drücken, um einen Anruf zu string.reverse() gefolgt zu setzen die Ziffern in der richtigen Reihenfolge. Ich überlasse das Benchmarking dem Studenten. Beachten Sie, dass der Code, den ich hier eingefügt habe, zwar ausgeführt wird und scheinbar korrekte Antworten erhält, es jedoch andere Möglichkeiten gibt, ihn weiter abzustimmen.

Zum Beispiel wird der allgemeine Fall der Basis 10 aussortiert und mit der eingebauten tostring() Funktion behandelt. Für die Basen 8 und 16, die Umwandlungsspezifikatoren für string.format() ("%o" bzw. "%x") haben, können jedoch ähnliche Culls durchgeführt werden.

Auch weder Nikolaus 'Lösung noch meine behandeln Nicht-Ganzzahlen besonders gut. Ich betone das hier, indem ich am Anfang den Wert n zu einer Ganzzahl mit math.floor() erzwinge.

Das korrekte Konvertieren eines allgemeinen Gleitkommawerts in eine beliebige Basis (gerade Basis 10) ist mit Feinheiten behaftet, die ich dem Leser als Übung überlasse.

3

Sie können eine Schleife verwenden, um eine Ganzzahl in eine Zeichenfolge zu konvertieren, die die erforderliche Basis enthält. für Basen unter 10 den folgenden Code verwenden, wenn man eine Base größer als muß, dass man eine Linie, die das Ergebnis von x% Base zu einem Zeichen mapps hinzufügen muß

x = 1234 
r = "" 
base = 8 

while x > 0 do 
    r = "" .. (x % base) .. r 
    x = math.floor(x/base) 
end 
print(r); 
+1

tnx iem neu zu lua. – Woland

+1

Vorsicht: Dies behandelt keine negativen oder nicht ganzzahligen Werte. Negativ ist einfach zu adressieren, man muss nur das Zeichen erkennen und es vor der Schleife positiv machen. Nicht-Ganzzahlen sind viel schwieriger. – RBerteig