How do i convert binary to decimal (LUA) - lua

I know that there's tonumber() function, but the problem is that i need to convert larger numbers like 1000100110100011111010101001001001001100100101 . I can write that by myself, but is there a way to integrate that in function? And if I write that in current function, it returns different number. For example: through wolfram alpha, I converted "Something" (base 36) to binary and got 10010011001100011001011110001100000110110101100.
If I put that in my custom function and convert back to base 36, I get 1Z141Z3 or 4294967295 (range for unassigned int)

In Lua 5.3, tonumber works just fine:
Lua 5.3.2 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> tonumber("1000100110100011111010101001001001001100100101",2)
37834277032741
> tonumber("10010011001100011001011110001100000110110101100",2)
80920602611116

Lua supports 64bit integers since 5.3. Is your Lua up to date?
Open http://www.lua.org/cgi-bin/demo
and execute this quick and dirty conversion. The result matches your quoted Wolfram Alpha number.
local dec = 80920602611116
local bin = "10010011001100011001011110001100000110110101100"
bin = string.reverse(bin)
local sum = 0
for i = 1, string.len(bin) do
num = string.sub(bin, i,i) == "1" and 1 or 0
sum = sum + num * math.pow(2, i-1)
end
print(sum)

Related

Concat bits into int in LUA

For a project, I need to convert a list of booleans into one int. I already did the concat of the values and I get a binary number with 16 bits :
The boolean values
My binary
But i now need to convert this binary number into an Int.
For example, this binary should have the value 32.
Is there any way to do this ? Is this even possible ? I hope my explanations were clear.
Thanks !
It is...
€ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> bin = '0.00.00.00.00.00.00.00.00.00.01.00.00.00.00.00.0'
> bin:gsub('%.0', '')
0000000000100000 16
> tonumber(bin:gsub('%.0', ''), 2)
32
string.gsub() https://www.lua.org/manual/5.4/manual.html#pdf-string.gsub
tonumber() https://www.lua.org/manual/5.4/manual.html#pdf-tonumber
PS: I am curious how you "already did the concat of the values and I get a binary number with 16 bits"
In fact bin has 17 values delimited with 16 dots.
I would do the following...
> bools = {false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false}
> #bools
16
> for k, v in pairs(bools) do bools[k] = v == true and 1 or 0 end
> table.concat(bools)
0000000000100000
> tonumber(table.concat(bools), 2)
32
-- Convert back to booleans
> for k, v in pairs(bools) do bools[k] = v == 1 and true or false end

How Can I Convert this Lua Code to be Able to be Used in Older Version? (What is the Order of Precedence of Lua Bitwise Operators?)

I have this Lua code in Lua 5.3 for Base64:
local bs = { [0] =
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
}
local function base64(s)
local byte, rep = string.byte, string.rep
local pad = 2 - ((#s-1) % 3)
s = (s..rep('\0', pad)):gsub("...", function(cs)
local a, b, c = byte(cs, 1, 3)
return bs[a>>2] .. bs[(a&3)<<4|b>>4] .. bs[(b&15)<<2|c>>6] .. bs[c&63]
end)
return s:sub(1, #s-pad) .. rep('=', pad)
end
I wanted to use it in older versions, but the problem is it does have the bitwise operators (not library). I can easily replace the symbols to the corresponding functions, but I don't know the precedence of Lua bitwise operators.

attempt to compare nil with number stack traceback?

I'm playing with Lua following this link: https://www.lua.org/pil/4.2.html and get confused about a point.
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> x=10
> local i=1
> while i<=x do
>> local x = i*2
>> print(x)
>> i=i+1
>> end
stdin:1: attempt to compare nil with number
stack traceback:
stdin:1: in main chunk
[C]: in ?
I guess this error message indicates that something is wrong with the expression while i<=x. Any comments are greatly appreciated.
EDIT: I just realize that it's probably because it does not work in a terminal.
It did not work out in an interactive terminal. Because local i=1 is understood by terminal as a chunk by itself once you hit enter. That is why the "attempt to compare nil with number" error; because i is not defined, i.e., nil in this case. To correct it, put the first two lines and the while loop inside of a do chuck as the following.
> do
>> x = 10
>> local i=1
>> while i<=x do
>> local x = i*2
>> print(x)
>> i = i+1
>> end
>> end
2
4
6
8
10
12
14
16
18
20
>
Actually the problem is in local i=1 try
> local i = 1
> print(i)
The problem is that when running the console, it seems that the line is a chunk and the variable is local inside that chunk.
you can fix that by using a global variable or you can do this
> local i = 1 do
>> print(i)
>> end
Which results in chunk structure like this [local i [print(i)]] therefore i can be accessed. Note also that local x = i*2 is valid since it is inside the while - do chunk.
Your code would also work correctly, if it was inside a Lua file.
I could reproduce the problem in Lua 5.3.4 as well.
If you read on in the Lua docs, chapter 4.2 – Local Variables and Blocks, you'll get to the sentence
Beware that this example will not work as expected if you enter it in interactive mode. The second line, local i = 1, is a complete chunk by itself.
This addresses exactly the issue in question. So it seems that the Lua interpreter has limited support for an outmost chunk (that is clearly present in a Lua file). But this behaviour seems to me acceptable and understandable in view of the compactness of language and interpreter.
So, when in interactive mode,
either leave out the local before variable i to make it work:
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
Lua>x=10
Lua>i=1
Lua>while i<=x do
...>local x=i*2
...>print(x)
...>i=i+1
...>end
or start enclose the whole by a block:
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
Lua>do
...>local x=10
...>local i=1
...>while i<=x do
...>local x=i*2
...>print(x)
...>i=i+1
...>end
...>end
Both options will produce to the regular (and expected) output:
2
4
6
8
10
12
14
16
18
20

Lua number currency format

In lua, how can I format a number to have 2 decimal places?
I have a value example: 25.333 and I want it to display 25.33 instead.
Sometimes it's an integer like 55 and I want it to display 55.00 instead. This is for displaying currency values. I've tried example formatting functions, and none do what I want.
Any advice is appreciated.
Jerry
See this answer. Basically, you'd want something like:
rdahlgren#deimos: pts/1: 5 files 48Kb$ lua
Lua 5.2.0 Copyright (C) 1994-2011 Lua.org, PUC-Rio
> x = 25
> y = 25.3333
> print(string.format("%.2f", x))
25.00
> print(string.format("%.2f", y))
25.33
>

Lua: converting from float to int

Even though Lua does not differentiate between floating point numbers and integers, there are some cases when you want to use integers. What is the best way to covert a number to an integer if you cannot do a C-like cast or without something like Python's int?
For example when calculating an index for an array in
idx = position / width
how can you ensure idx is a valid array index? I have come up with a solution that uses string.find, but maybe there is a method that uses arithmetic that would obviously be much faster. My solution:
function toint(n)
local s = tostring(n)
local i, j = s:find('%.')
if i then
return tonumber(s:sub(1, i-1))
else
return n
end
end
You could use math.floor(x)
From the Lua Reference Manual:
Returns the largest integer smaller than or equal to x.
Lua 5.3 introduced a new operator, called floor division and denoted by //
Example below:
Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
>12//5
2
More info can be found in the lua manual
#Hofstad is correct with the math.floor(Number x) suggestion to eliminate the bits right of the decimal, you might want to round instead. There is no math.round, but it is as simple as math.floor(x + 0.5). The reason you want to round is because floats are usually approximate. For example, 1 could be 0.999999996
12.4 + 0.5 = 12.9, floored 12
12.5 + 0.5 = 13, floored 13
12.6 + 0.5 = 13.1, floored 13
local round = function(a, prec)
return math.floor(a + 0.5*prec) -- where prec is 10^n, starting at 0
end
why not just use math.floor()? it would make the indices valid so long as the numerator and denominator are non-negative and in valid ranges.

Resources