convert a number to binary with lua ?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: convert a number to binary with lua ?

Post by zorg »

okay, that's a simple thing then; rgba values are usually unsigned.

Code: Select all

-- Converts a byte to a string of 0s and 1s.
function byte2bin(n)
local t = {}
  for i=7,0,-1 do
    t[#t+1] = math.floor(n / 2^i)
    n = n % 2^i
  end
  return table.concat(t)
end
This can be extended to larger numbers too, automatically: (hopefully i didn't fudge up the decimal digit calculation...)

Code: Select all

-- Converts a byte to a string of 0s and 1s.
function byte2bin(n)
local t, d = {}, 0
  d = math.log(n)/math.log(2) -- binary logarithm
  for i=math.floor(d+1),0,-1 do
    t[#t+1] = math.floor(n / 2^i)
    n = n % 2^i
  end
  return table.concat(t)
end
-- And negatives:

Code: Select all

-- Converts a byte to a string of 0s and 1s.
function byte2bin(n)
  local t, d = {}, 0
  d = math.log(n)/math.log(2) -- binary logarithm
  if n<0 then
    -- two's complement
    d = d + 1
    n = 2^d - math.abs(n)
  end
  for i=math.floor(d+1),0,-1 do
    n = n % 2^i
  end
  return table.concat(t)
end
fractions are trickier; fixed-point notation would be doable, but computers nowadays usually use the IEEE floating point representations, and those are hard to code by hand like this.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Tuxion
Prole
Posts: 14
Joined: Mon Jan 08, 2018 6:31 pm

Re: convert a number to binary with lua ?

Post by Tuxion »

Thank you very much, that's exactly what I wanted to know.

Should I use the same method if I want to convert to hexadecimal?
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: convert a number to binary with lua ?

Post by zorg »

You could change a few things to have that, mostly the number 2s in a few lines... but on the other hand:

Code: Select all

n = 154
print(('%X'):format(n))
the format string also works with %x (lowercase x) if you prefer the hex digits lowercase.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
pgimeno
Party member
Posts: 3674
Joined: Sun Oct 18, 2015 2:58 pm

Re: convert a number to binary with lua ?

Post by pgimeno »

Float isn't very difficult. math.frexp does the heavy lifting.

Code: Select all

local function int2bin(n)
  local result = ''
  while n ~= 0 do
    if n % 2 == 0 then
      result = '0' .. result
    else
      result = '1' .. result
    end
    n = math.floor(n / 2)
  end
  return result
end

local function float2bin(n)
  if math.abs(n) == math.huge then
    -- plus or minus infinity
    return n > 0 and 'inf' or '-inf'
  end
  if not n == n then
    -- nan
    return 'nan'
  end

  local m, e = math.frexp(n)
  local result = int2bin(math.abs(m * 2^53))

  local len = #result
  if e > 53 then
    -- big number, add zeros on the right
    result = result .. ('0'):rep(e - 53)
  elseif e < 1 then
    -- small number, add zeros on the left
    result = ('0'):rep(1 - e) .. result
    e = 1
  end

  -- Add the point
  result = result:sub(1, e) .. '.' .. result:sub(e + 1)

  -- remove zeros on the right including point
  result = result:gsub('%.?0*$', '')

  if n < 0 then
    return '-' .. result
  end
  return result
end

repeat
  io.write('> ')
  local s = io.read('*line')
  if s == nil or s == '' then io.write('\n') break end
  print(float2bin(loadstring('return (' .. s .. ')')()))
until false
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: convert a number to binary with lua ?

Post by zorg »

Yes but that's sure as hell not the binary representation of an IEEE single or double precision float :P
Also, concatenation is still slower than tables, that said, your code for int2bin is simpler than mine, since it avoids logarithms and stuff... though not sure if it could handle signed ints without it.

Code: Select all

local function int2bin(n)
  local result = {}
  while n ~= 0 do
    if n % 2 == 0 then
      result[#result+1] = '0'
    else
      result[#result+1] = '1'
    end
    n = math.floor(n / 2)
  end
  return table.concat(result)
end
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
pgimeno
Party member
Posts: 3674
Joined: Sun Oct 18, 2015 2:58 pm

Re: convert a number to binary with lua ?

Post by pgimeno »

Yeah, I optimized for clarity, not speed :)

Edit: And, well, it's the binary representation of the number that the float represents, which I thought was what was asked.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: convert a number to binary with lua ?

Post by ivan »

Tuxion, the standard way is to format the number as a hex:

Code: Select all

hex = string.format("%x", number)
print(hex)
"%06x" RGB, 6 digits
"%08x" RGBA, 8 digits
Printing as binary is possible but it's just not very practical/common.

PS. But if you insist on printing binary:

Code: Select all

local h2b = {
['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'
}
function hex2bin(n)
  return n:upper():gsub(".", h2b)
end
function dec2bin(n)
  return hex2bin(tostring(n):format("%X"))
end
Nice and simple, no math involved!
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 7 guests