Page 2 of 2
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 11:52 am
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.
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 12:59 pm
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?
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 1:10 pm
by zorg
You could change a few things to have that, mostly the number 2s in a few lines... but on the other hand:
the format string also works with %x (lowercase x) if you prefer the hex digits lowercase.
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 3:10 pm
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
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 4:40 pm
by zorg
Yes but that's sure as hell not the binary representation of an IEEE single or double precision float
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
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 5:07 pm
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.
Re: convert a number to binary with lua ?
Posted: Sat Mar 10, 2018 5:49 pm
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!