This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

bit operation returns negative number that doesn’t make sense

0

Hi,

This may be a pure Lua question (I'm using Lua to write a dissector). I haven't got any responses from the Lua forum so I'm here for help.

I have this line of code using bit op which is embedded in the Wireshark Lua tool. This is a regular bitwise and operation, not the 64bit version.

a = bit.band(0xb5ffffff, 0xffffffff) It returns: -1241513985.

How come? It should return the first argument, in decimal, which is 3053453311.

What's going on?

asked 06 Mar '14, 09:03

YXI's gravatar image

YXI
21182023
accept rate: 0%

retagged 06 Mar '14, 09:50

Hadriel's gravatar image

Hadriel
2.7k2939


2 Answers:

2

Wireshark's bitop library is based on Mike Pall's bitop library (see here). As described in the semantics page of the documentation, in the fifth bullet point about ranges:

  • But the Lua number type must be signed and may be limited to 32 bits. Defining the result type as an unsigned number would not be cross-platform safe. All bit operations are thus defined to return results in the range of signed 32 bit numbers (converted to the Lua number type).

answered 06 Mar '14, 09:44

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

BTW, yeah I know that's weird - I understand why it was done that way in the generic bitop library... but for Wireshark since we know we use doubles for our Lua numbers we could have changed that behavior. But I wasn't the one who imported that library, and it's been in wireshark for a long time it seems, so changing its behavior isn't safe (in theory).

(06 Mar '14, 09:49) Hadriel

Oh, thanks.
Since at this stage I'm just interested in the bit manipulation and don't need the value, I can just leave everything as is. Later on when I do need the value, I can do a 2's complement if the first bit of the value is 1. As a matter of fact, I was planning to use Struct pack() and unpack() to convert unsigned numbers to signed numbers after I do the bit operations. If the bit operations are already interpreting my numbers as signed, then I don't need to do the conversion using Struct? Or I should still do it since the struct conversion is more universal, especially the system independent in/In options?

(06 Mar '14, 11:44) YXI

Well that's a new question, so a new ask.wireshark.org topic. :)

(06 Mar '14, 13:09) Hadriel

I kind of figured out my own answer. Just do the bit operations and then use the Struct pack() and unpack() to convert to signed numbers if I need to. This way I don't have to worry about checking MSB or calculate two's complement.

(06 Mar '14, 13:11) YXI

But why go to all the trouble? Why not just do:

local function unsign(n)
    if n < 0 then
        n = 4294967296 + n
    end
    return n
end

local a = unsign( bit.band(0xb5ffffff, 0xffffffff) ) …

Won’t that do it? (I haven’t tried, but it looks right, though it’s late at night where I am right now…)

(06 Mar ‘14, 13:30) Hadriel

Because I have a lot of different values that need different conversions based on each one’s requirement. Some may be from unsigned to signed, some from Big Endian to Little Endian, and some from long long to double. With pack, unpack functions I can treat them all with the same two steps and simply pass the format dynamically.

(06 Mar ‘14, 20:20) YXI
showing 5 of 6 show 1 more comments

0

There's a conversion to signed going on somewhere. A 32 bit signed value of -1241513985 is represented by 0xb5ffffff. I don't know Lua so can't help you any further.

answered 06 Mar '14, 09:13

grahamb's gravatar image

grahamb ♦
19.8k330206
accept rate: 22%

edited 06 Mar '14, 09:13