2012-01-31 18 views
9

Come si può rappresentare un numero intero come Binario?Lua: print integer as binary

in modo da poter stampare 7 come 111

+0

Dai un'occhiata [qui] (http://lua-users.org/lists/lua-l/2002-10/msg00245.html) (Immagino che non ci sia una funzione integrata?) –

+0

non è aggiornato un po ' :) – fl00r

risposta

5

si scrive una funzione per fare questo.

num=7 
function toBits(num) 
    -- returns a table of bits, least significant first. 
    local t={} -- will contain the bits 
    while num>0 do 
     rest=math.fmod(num,2) 
     t[#t+1]=rest 
     num=(num-rest)/2 
    end 
    return t 
end 
bits=toBits(num) 
print(table.concat(bits)) 

In Lua 5,2 hai già hanno funzioni bit a bit che può aiutare (bit32)


Qui è il più significativo, prima versione, con optional che porta 0 imbottitura per un numero specificato di bit:

function toBits(num,bits) 
    -- returns a table of bits, most significant first. 
    bits = bits or math.max(1, select(2, math.frexp(num))) 
    local t = {} -- will contain the bits   
    for b = bits, 1, -1 do 
     t[b] = math.fmod(num, 2) 
     num = math.floor((num - t[b])/2) 
    end 
    return t 
end 
+1

hai bit invertiti nella tua funzione, quindi '20' restituirà' 00101', non '10100' – fl00r

+1

non hai specificato se volevi big o little endian. Anche l'esempio non lo ha dato, poiché 111 è un palindromo;). Ad ogni modo, adattarlo è semplice: basta usare 'nBits = ceiling (select (2, math.frexp (num)))' e usare un ciclo for a partire da nBits andando a 1. – jpjacobs

+0

colpa mia, scusa, tuttavia la risposta è giusto e utile, grazie! – fl00r

0
function reverse(t) 
    local nt = {} -- new table 
    local size = #t + 1 
    for k,v in ipairs(t) do 
    nt[size - k] = v 
    end 
    return nt 
end 

function tobits(num) 
    local t={} 
    while num>0 do 
     rest=num%2 
     t[#t+1]=rest 
     num=(num-rest)/2 
    end 
    t = reverse(t) 
    return table.concat(t) 
end 
print(tobits(7)) 
# 111 
print(tobits(33)) 
# 100001 
print(tobits(20)) 
# 10100 
+2

Un altro wa y è 'string.reverse (table.concat (t))' – user3125367

2
function bits(num) 
    local t={} 
    while num>0 do 
     rest=num%2 
     table.insert(t,1,rest) 
     num=(num-rest)/2 
    end return table.concat(t) 
end 

Dato che nessuno vuole utilizzare table.insert mentre è utile qui

+0

In realtà, usando table.insert aumenta la complessità dell'algoritmo ** da O (n) ** a ** O (n^2) **. Fare ciò che ha detto ** jpjacobs ** nel suo commento, prima determinare la lunghezza del numero e poi riempire l'array all'indietro, è molto più efficiente. Soprattutto per grandi numeri. Le uniche modifiche sarebbero sostituire 'while num> 0 do' di' per i = math.ceil (selezionare (2, math.frexp (num))), 1, -1 do' e 't [# t + 1 ] 'per' t [i] '. – RPFeltz

2

Ecco una funzione ispirata alla risposta accettata con una sintassi corretta che restituisce una tabella di bit in wriiten da destra a sinistra.

num=255 
bits=8 
function toBits(num, bits) 
    -- returns a table of bits 
    local t={} -- will contain the bits 
    for b=bits,1,-1 do 
     rest=math.fmod(num,2) 
     t[b]=rest 
     num=(num-rest)/2 
    end 
    if num==0 then return t else return {'Not enough bits to represent this number'}end 
end 
bits=toBits(num, bits) 
print(table.concat(bits)) 

>>11111111 
2

C'è un modo più veloce per fare questo, che sfrutta string.format, che converte i numeri in base 8. È banale quindi convertire base 8 in binario.

--create lookup table for octal to binary 
oct2bin = { 
    ['0'] = '000', 
    ['1'] = '001', 
    ['2'] = '010', 
    ['3'] = '011', 
    ['4'] = '100', 
    ['5'] = '101', 
    ['6'] = '110', 
    ['7'] = '111' 
} 
function getOct2bin(a) return oct2bin[a] end 
function convertBin(n) 
    local s = string.format('%o', n) 
    s = s:gsub('.', getOct2bin) 
    return s 
end 

Se si vuole tenerli tutti della stessa dimensione, quindi fare

s = string.format('%.22o', n) 

Che si ottiene 66 bit. Questo è due bit in più alla fine, poiché ottale funziona in gruppi di 3 bit e 64 non è divisibile per 3. Se vuoi 33 bit, cambialo in 11.

Se hai la libreria BitOp, che è disponibili per impostazione predefinita in LuaJIT, allora si può fare questo:

function convertBin(n) 
    local t = {} 
    for i = 1, 32 do 
     n = bit.rol(n, 1) 
     table.insert(t, bit.band(n, 1)) 
    end 
    return table.concat(t) 
end 

Ma notare che questo fa solo i primi 32 bit! Se il tuo numero è maggiore di 2^32, il risultato non sarà corretto.