Here is my code. two num plus > 0 but add a variable < 0 !!!
function addExp(actorExp, val)
local actorExp = actorExp -- actorExp = 800000000
local val = val -- val = 3000000000
if actorExp + val -- Here actorExp > 0 then
-- actorExp + val > 0 but
actorExp = actorExp + val -- Here actorExp = -2147483648 ???
else return end
updateInfo(actor)
end
how can i fix it
This is called an overflow error.
The way computers store data is using binary (1s and 0s), and depending on the size (number of digits) of the binary used to store each number (often 32 'bits') will determine the maximum value. When the maximum value is reached, it will "overflow" back to the start, which in this case is -2147483648 as it is a "signed" (can be negative) number.
I am writing a wireshark dissector of a custom protocol using LUA.For this custom protocol,there are no underlying TCP port or UDP port hence i have written a postdissector.
I am able to capture the payload from the below layers and convert it into a string.
local io_b = tostring(customprotocol)
After this, io_b has the following data
io_b = 10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00
At first I split this string with : as the seperator and copy the elements into an array/table.
datafields = {}
index = 1
for value in string.gmatch(io_b, "[^:]+") do
datafields[index] = value
index = index + 1
end
Then I read each element of the datafield array as a uint8 value and check if a bit is set in that datafield element.How to make sure that each element of the table is uint8?
function lshift(x, by)
return x * 2 ^ by
end
--checks if a bit is set at a position
function IsBitSet( b, pos)
if b ~= nil then
return tostring(bit32.band(tonumber(b),lshift(1,pos)) ~= 0)
else
return "nil"
end
end
Then I want to display the value of each bit in the wireshark.I dont care about the first four bytes. The script displays each bit of the 5th byte(which is the 1st considered byte) correctly but displays all the bits value of the 6th byte and other remaining bytes as "nil".
local data_in_2 = subtree:add(customprotocol,"secondbyte")
data_in_2:add(firstbit,(IsBitSet((datafields[6]),7)))
data_in_2:add(secondbit,(IsBitSet((datafields[6]),6)))
data_in_2:add(thirdbit,(IsBitSet((datafields[6]),5)))
data_in_2:add(fourbit,(IsBitSet((datafields[6]),4)))
data_in_2:add(fivebit,(IsBitSet((datafields[6]),3)))
data_in_2:add(sixbit,(IsBitSet((datafields[6]),2)))
data_in_2:add(sevenbit,(IsBitSet((datafields[6]),1)))
data_in_2:add(eightbit,(IsBitSet((datafields[6]),0)))
What am i doing wrong?
Maybe i am wrong but it seems you can do it simpler with...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Now replace all : on the fly with nothing and convert it with #Egor' comment tip
-- Simply by using string method gsub() from within io_b
b_num = tonumber(io_b:gsub('%:', ''), 16)
print(b_num)
-- Output: 537526272
#shakingwindow - I cant comment so i ask here...
Do you mean...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Converting HEX to string - Replacing : with ,
io_hex = io_b:gsub('[%x]+', '"%1"'):gsub(':', ',')
-- Converting string to table
io_hex_tab = load('return {' .. io_hex .. '}')()
-- Put out key/value pairs by converting HEX value string to a number on the fly
for key, value in pairs(io_hex_tab) do
print(key, '=', tonumber(value, 16))
end
...that puts out...
1 = 16
2 = 16
3 = 16
4 = 16
5 = 1
6 = 15
7 = 0
8 = 13
9 = 0
10 = 0
11 = 0
12 = 0
13 = 1
14 = 0
15 = 0
16 = 0
17 = 0
18 = 32
19 = 10
20 = 0
21 = 0
...?
I want to perform set and reset of particular bit in a number. As I'm using lua 5.1 I can't able to use APIs and shifting operators so it is becoming more and more complex so please help me finding this
bit library is shipped with the firmware.
Read the documentation: https://nodemcu.readthedocs.io/en/release/modules/bit/
You can do it without external libraries, if you know the position of the bit you wish to flip.
#! /usr/bin/env lua
local hex = 0xFF
local maxPos = 7
local function toggle( num, pos )
if pos < 0 or pos > maxPos then print( 'pick a valid pos, 0-' ..maxPos )
else
local bits = {} -- populate emtpy table
for i=1, maxPos do bits[i] = false end
for i = maxPos, pos +1, -1 do -- temporarily throw out the high bits
if num >= 2 ^i then
num = num -2 ^i
bits [i +1] = true
end
end
if num >= 2 ^pos then num = num -2 ^pos -- flip desired bit
else num = num +2 ^pos
end
for i = 1, #bits do -- add those high bits back in
if bits[i] then num = num +2 ^(i -1) end
end
end ; print( 'current value:', num )
return num
end
original value: 255
current value: 127
pick a valid pos, 0-7
current value: 127
current value: 255
I am writing code in gfortran to separate a variable time stamp into its separate parts of year, month, and day. I have written this code so the user can input what the time stamp format will be (ie. YEAR/MON/DAY, DAY/MON/YEAR, etc). This creates a total of 6 possible combinations. I have written code that attempts to deal with this, but I believe it to be ugly and poorly done.
My current code uses a slew of 'if' and 'goto' statements. The user provides 'tsfo', the time stamp format. 'ts' is a character array containing the time stamp data (as many as 100,000 time stamps). 'tsdelim' is the delimiter between the year, month, and day. I must loop from 'frd' (the first time stamp) to 'nlines' (the last time stamp).
Here is the relevant code.
* Choose which case to go to.
first = INDEX(tsfo,tsdelim)
second = INDEX(tsfo(first+1:),tsdelim) + first
if (INDEX(tsfo(1:first-1),'YYYY') .ne. 0) THEN
if (INDEX(tsfo(first+1:second-1),'MM') .ne. 0) THEN
goto 1001
else
goto 1002
end if
else if (INDEX(tsfo(1:first-1),'MM') .ne. 0) THEN
if (INDEX(tsfo(first+1:second-1),'DD') .ne. 0) THEN
goto 1003
else
goto 1004
end if
else if (INDEX(tsfo(1:first-1),'DD') .ne. 0) THEN
if (INDEX(tsfo(first+1:second-1),'MM') .ne. 0) THEN
goto 1005
else
goto 1006
end if
end if
first = 0
second = 0
* Obtain the Julian Day number of each data entry.
* Acquire the year, month, and day of the time stamp.
* Find 'first' and 'second' and act accordingly.
* Case 1: YYYY/MM/DD
1001 do i = frd,nlines
first = INDEX(ts(i),tsdelim)
second = INDEX(ts(i)(first+1:),tsdelim) + first
read (ts(i)(1:first-1), '(i4)') Y
read (ts(i)(first+1:second-1), '(i2)') M
read (ts(i)(second+1:second+2), '(i2)') D
* Calculate the Julian Day number using a function.
temp1(i) = JLDYNUM(Y,M,D)
end do
goto 1200
* Case 2: YYYY/DD/MM
1002 do i = frd,nlines
first = INDEX(ts(i),tsdelim)
second = INDEX(ts(i)(first+1:),tsdelim) + first
read (ts(i)(1:first-1), '(i4)') Y
read (ts(i)(second+1:second+2), '(i2)') M
read (ts(i)(first+1:second-1), '(i2)') D
* Calculate the Julian Day number using a function.
temp1(i) = JLDYNUM(Y,M,D)
end do
goto 1200
* Onto the next part of the code
1200 blah blah blah
I believe this code will work, but I do not think it is a very good method. Is there a better way to go about this?
It is important to note that the indices 'first' and 'second' must be calculated for each time stamp as the month and day can both be represented by 1 or 2 integers. The year is always represented by 4.
With only six permutations to handle I would just build a look-up table with the whole tsfo string as the key and the positions of year, month and day (1st, 2nd or 3rd) as the values. Any unsupported formats should produce an error, which I haven't coded below. When subsequently you loop though your ts list and split an item you know which positions to cast to the year, month and day integer variables:
PROGRAM timestamp
IMPLICIT NONE
CHARACTER(len=10) :: ts1(3) = ["2000/3/4 ","2000/25/12","2000/31/07"]
CHARACTER(len=10) :: ts2(3) = ["3/4/2000 ","25/12/2000","31/07/2000"]
CALL parse("YYYY/DD/MM",ts1)
print*
CALL parse("DD/MM/YYYY",ts2)
CONTAINS
SUBROUTINE parse(tsfo,ts)
IMPLICIT NONE
CHARACTER(len=*),INTENT(in) :: tsfo, ts(:)
TYPE sti
CHARACTER(len=10) :: stamp = "1234567890"
INTEGER :: iy = -1, im = -1, id = -1
END TYPE sti
TYPE(sti),PARAMETER :: stamps(6) = [sti("YYYY/MM/DD",1,2,3), sti("YYYY/DD/MM",1,3,2),&
sti("MM/DD/YYYY",2,3,1), sti("DD/MM/YYYY",3,2,1),&
sti("MM/YYYY/DD",2,1,3), sti("DD/YYYY/MM",3,1,2)]
TYPE(sti) :: thisTsfo
INTEGER :: k, k1, k2
INTEGER :: y, m, d
CHARACTER(len=10) :: cc(3)
DO k=1,SIZE(stamps)
IF(TRIM(tsfo) == stamps(k)%stamp) THEN
thisTsfo = stamps(k)
EXIT
ENDIF
ENDDO
print*,thisTsfo
DO k=1,SIZE(ts)
k1 = INDEX(ts(k),"/")
k2 = INDEX(ts(k),"/",BACK=.TRUE.)
cc(1) = ts(k)(:k1-1)
cc(2) = ts(k)(k1+1:k2-1)
cc(3) = ts(k)(k2+1:)
READ(cc(thisTsfo%iy),'(i4)') y
READ(cc(thisTsfo%im),'(i2)') m
READ(cc(thisTsfo%id),'(i2)') d
PRINT*,ts(k),y,m,d
ENDDO
END SUBROUTINE parse
END PROGRAM timestamp
I would encode the different cases in another way, like this:
module foo
implicit none
private
public encode_datecode
contains
integer function encode_datecode(datestr, sep)
character(len=*), intent(in) :: datestr, sep
integer :: first, second
character(len=1) :: c1, c2, c3
first = index(datestr, sep)
second = index(datestr(first+1:), sep) + first
c1 = datestr(1:1)
c2 = datestr(first+1:first+1)
c3 = datestr(second+1:second+1)
foo = num(c1) + 3*num(c2) + 9*num(c3)
end function encode_datecode
integer function num(c)
character(len=1) :: c
if (c == 'Y') then
num = 0
else if (c == 'M') then
num = 1
else if (c == 'D') then
num = 2
else
stop "Illegal character"
end if
end function num
end module foo
and then handle the legal cases (21, 15, 19, 7, 11, 5) in a SELECT statement.
This takes advantage of the fact that there won't be a 'YDDY/MY/YM' format.
If you prefer better binary or decimal readability, you can also multiply by four or by 10 instead of 3.
I have some constraints like so:
interesting = 0x1
choked = 0x2
remote_interested = 0x4
remote_choked = 0x8
supports_extensions = 0x10
local_connection = 0x20
handshake = 0x40
connecting = 0x80
queued = 0x100
on_parole = 0x200
seed = 0x400
optimistic_unchoke = 0x800
rc4_encrypted = 0x100000
plaintext_encrypted = 0x200000
and the documentation tells me 'The flags attribute tells you in which state the peer is in. It is set to any combination of the enums above' so basically I call the dll and it fills in the structure with a decimal number representing the flag values, a few examples:
2086227
170
2098227
106
How do I from the decimal determine the flags?
In order to determine which flags were set, you need to use the bitwise AND operation (bit32.band() in Lua 5.2). For example:
function hasFlags(int, ...)
local all = bit32.bor(...)
return bit32.band(int, all) == all
end
if hasFlags(2086227, interesting, local_connection) then
-- do something that has interesting and local_connection
end