fl00r
fl00r

Reputation: 83680

Lua: print integer as a binary

How can I represent integer as Binary?

so I can print 7 as 111

Upvotes: 22

Views: 40025

Answers (10)

dnaldoog
dnaldoog

Reputation: 49

This function uses a lookup table to print a binary number extracted from a hex representation. All using string manipulation essentially. Tested in lua 5.1.

local bin_lookup = {
    ["0"] = "0000",
    ["1"] = "0001",
    ["2"] = "0010",
    ["3"] = "0011",
    ["4"] = "0100",
    ["5"] = "0101",
    ["6"] = "0110",
    ["7"] = "0111",
    ["8"] = "1000",
    ["9"] = "1001",
    ["A"] = "1010",
    ["B"] = "1011",
    ["C"] = "1100",
    ["D"] = "1101",
    ["E"] = "1110",
    ["F"] = "1111"
}

local print_binary = function(value)
    local hs = string.format("%.2X", value) -- convert number to HEX
    local ln, str = hs:len(), "" -- get length of string
    for i = 1, ln do -- loop through each hex character
        local index = hs:sub(i, i) -- each character in order
        str = str .. bin_lookup[index] -- lookup a table
        str = str .. " " -- add a space
    end
    return str
end

print(print_binary(45))
#0010 1101
print(print_binary(65000))
#1111 1101 1110 1000

Upvotes: 3

darkfrei
darkfrei

Reputation: 521

As by Dave, but with filled empty bits:

local function toBits(num, bits)
    -- returns a table of bits, least significant first.
    local t={} -- will contain the bits
    bits = bits or 8
    while num>0 do
        rest=math.fmod(num,2)
        t[#t+1]=rest
        num=math.floor((num-rest)/2)
    end
    for i = #t+1, bits do -- fill empty bits with 0
        t[i] = 0
    end
    return t
end

for i = 0, 255 do
    local bits = toBits(i)
    print(table.concat(bits, '  '))
end

Result:

  0   0   0   0   0   0   0   0
  1   0   0   0   0   0   0   0
  0   1   0   0   0   0   0   0
  1   1   0   0   0   0   0   0
  0   0   1   0   0   0   0   0
  1   0   1   0   0   0   0   0
  ...
  0   1   1   1   1   1   1   1
  1   1   1   1   1   1   1   1

Upvotes: 0

Shewer Lu
Shewer Lu

Reputation: 11

local function tobits(num, str) -- tail call
    str = str or "B"
    if num == 0 then return str end 
    return tobits( 
          num >> 1 , -- right shift
          ((num & 1)==1 and "1" or "0") .. str   )
end          

Upvotes: 1

lucullus
lucullus

Reputation: 217

local function tobinary( number )
  local str = ""
  if number == 0 then
      return 0
  elseif number < 0 then
      number = - number
      str = "-"
  end
  local power = 0
  while true do
      if 2^power > number then break end
      power = power + 1
  end
  local dot = true
  while true do
      power = power - 1
      if dot and power < 0 then
          str = str .. "."
          dot = false
      end
      if 2^power <= number then
          number = number - 2^power
          str = str .. "1"
      else
          str = str .. "0"
      end
      if number == 0 and power < 1 then break end
  end
  return str
end

May seem more verbose but it is actually faster than other functions that use the math library functions. Works with any number, be it positive/negative/fractional...

Upvotes: 2

Foxie Flakey
Foxie Flakey

Reputation: 420

This maybe not work in lua that has no bit32 library

    function toBinary(number, bits)
        local bin = {}
        bits = bits - 1
        while bits >= 0 do --As bit32.extract(1, 0) will return number 1 and bit32.extract(1, 1) will return number 0
                       --I do this in reverse order because binary should like that
            table.insert(bin, bit32.extract(number, bits))
            bits = bits - 1
        end
        return bin
    end
    --Expected result 00000011
    print(table.concat(toBinary(3, 8)))

This need at least lua 5.2 (because the code need bit32 library)

Upvotes: 0

jpjacobs
jpjacobs

Reputation: 9549

You write a function to do this.

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 you've already have bitwise functions which can help you ( bit32 )


Here is the most-significant-first version, with optional leading 0 padding to a specified number of 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

Upvotes: 16

Houshalter
Houshalter

Reputation: 2788

There's a faster way to do this that takes advantage of string.format, which converts numbers to base 8. It's trivial to then convert base 8 to binary.

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

If you want to keep them all the same size, then do

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

Which gets you 66 bits. That's two extra bits at the end, since octal works in groups of 3 bits, and 64 isn't divisible by 3. If you want 33 bits, change it to 11.

If you have the BitOp library, which is available by default in LuaJIT, then you can do this:

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

But note this only does the first 32 bits! If your number is larger than 2^32, the result wont' be correct.

Upvotes: 10

Ben
Ben

Reputation: 1301

Here is a function inspired by the accepted answer with a correct syntax which returns a table of bits in wriiten from right to left.

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

Upvotes: 3

einsteinK
einsteinK

Reputation: 49

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

Since nobody wants to use table.insert while it's useful here

Upvotes: 4

fl00r
fl00r

Reputation: 83680

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

Upvotes: 1

Related Questions