2012-01-31 15 views
9

¿Cómo puedo representar un número entero como binario?Lua: imprimir entero como un binario

para que pueda imprimir 7 como 111

+0

Echa un vistazo [aquí] (http://lua-users.org/lists/lua-l/2002-10/msg00245.html) (¿Supongo que no hay una función incorporada?) –

+0

está fuera de fecha un poco :) – fl00r

Respuesta

5

escribe una función para hacer esto.

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)) 

En Lua 5.2 que ya ha tienen funciones a nivel de bits que puede ayudarle (bit32)


Aquí es el más significativo primera versión, con el relleno opcional 0 conduce a un número especificado de bits:

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

tiene bits invertidos en su función, por lo que '20' devolverá' 00101', no '10100' – fl00r

+1

que no indicó si deseaba big o little endian. El ejemplo tampoco lo delató, ya que 111 es un palíndromo;). De todos modos, adaptarlo es fácil: simplemente use 'nBits = techo (select (2, math.frexp (num)))' y use un for-loop que empiece en nBits yendo a 1. – jpjacobs

+0

mi culpa, lo siento, sin embargo, la respuesta es correcto y útil, ¡gracias! – 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

Otro wa y es '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 

Dado que nadie quiere usar table.insert mientras sea útil aquí

+0

En realidad, usar table.insert aumenta la complejidad del algoritmo ** de O (n) ** a ** O (n^2) **. Hacer lo que ** jpjacobs ** dijo en su comentario, primero determinar la longitud del número y luego llenar el conjunto hacia atrás, es mucho más eficiente. Especialmente para grandes números. Los únicos cambios serían reemplazar 'while num> 0 do' por' for i = math.ceil (select (2, math.frexp (num))), 1, -1 do' y 't [# t + 1 ] 'por' t [i] '. – RPFeltz

2

Aquí hay una función inspirada en la respuesta aceptada con una sintaxis correcta que devuelve una tabla de bits escrita de derecha a izquierda.

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

Hay una manera más rápida de hacer esto que se aprovecha de string.format, que convierte números a base 8. Es trivial para luego convertir de base 8 a 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 

Si desea mantenerlos todos del mismo tamaño, y luego hacer

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

que te lleva 66 bits. Eso es dos bits adicionales al final, ya que octal funciona en grupos de 3 bits y 64 no es divisible por 3. Si quiere 33 bits, cámbielo a 11.

Si tiene la biblioteca BitOp, que es disponible por defecto en LuaJIT, entonces puede hacer esto:

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 

¡Pero tenga en cuenta que esto solo tiene los primeros 32 bits! Si su número es mayor que 2^32, el resultado no será correcto.

Cuestiones relacionadas