Integer Size...

Previous topic - Next topic

bigtunacan

I was getting some unexpected results and some bitwise operations I was trying to perform when reading map data in from the popular level editor, Tiled.

Tiled stored vertical and horizontal flipping along with the tile data by using a bitwise or in the file output.  So I try to pull this back out when loading the map in.  The problem appears to be though that the horizontal flipping is too large of a number for the way I'm handling it.  Below I plugged in some sample code of what I tried to do.  The check for the vertical flip worked as expected; it prints out 1073741824.  The horizontal flip prints 0.

Code (glbasic) Select

CONSTANT FLIPPED_VERT = 1073741824
CONSTANT FLIPPED_HORZ = 2147483648

PRINT "and_vert:" + bAND(FLIPPED_VERT, 1073741825),0,300
PRINT "and_horz:" + bAND(FLIPPED_HORZ, 2147483648),0,320

Ruidesco

It seems that FLIPPED_HORZ is a number above what a signed 32bit integer can be on the positive range.

bigtunacan

I understand that is what's happening. I'm a little surprised though since the below is straight out of the docs.
I thought based on this that when compiling for Windows I would get 64bits.  If this is not the case is there some type of work around; an equivalent of BIGINT in other languages?

Quote
Data Types

Numbers
On "big" systems, GLBasic's default storage for numbers uses 8 bytes (64 bits). To indicate that a variable is a number you can (optionally) append a '#' to the variable name to make this clear.
These numbers are otherwise known as "double precision floating-point numbers".

On "small" systems (those with ARM processors - PocketPC, GP2X, WIZ etc), numbers are stored as 4 bytes (32 bits). These are also known as "single precision floating point numbers".

Number variables ending with a '%' are integer numbers with a 4 byte (32 bit) accuracy.

Falstaff

Hm yeah odd behaviour.. Of course it looks like the difference between a signed or unsigned 32 bit integer. Computers will typically use the most significant bit to store the sign..

from the docs on bAND():

Quote
Performs the boolean AND operation on integer values. The numbers are 32bits in size.

I guess bAND must use signed ints.. so I saw you could sort of hack around this problem by ANDing the negative 31 bit number that you were using in your code:

Code (glbasic) Select

CONSTANT FLIPPED_VERT = 1073741824
CONSTANT FLIPPED_HORZ = -FLIPPED_VERT

DEBUG "and_vert:" + bAND(FLIPPED_VERT, 1073741825) + "\n"
DEBUG "and_horz:" + bAND(FLIPPED_HORZ, 2147483648) + "\n"


which outputs:

Code (glbasic) Select
and_vert:1073741824
and_horz:-2147483648


It's not ideal but at least it's non-zero; ie not false!

Kitty Hello

Try writing the numbers in hex format:
flipped = 0x10000000 e.g.

bigtunacan

Writing the number to hex format gives me a result that is off by one.  Instead of getting 2147483648 back I get back 2147483647; additionally this would cause extra effort to try and convert my incoming values from the file from decimal to hex to make these comparisons.  Seems like the solution Falstaff presents would be workable.  I ended up inline-ing it instead with the following.

Code (glbasic) Select

INLINE

int a,b;
a = (int) FLIPPED_HORZ;
b = (int) tmp_num;   
ret = a & b;
ENDINLINE


I like this because I'm still using the standard bitwise AND type of operation which is more understandable to me if I have to go back to my code down the road and try to remember what is going on.  It also returns -2147483648, like the solution presented by Falstaff, so once I'm outside of the INLINE I just grab the ABS value of the result.  This seems to work ok, albeit slightly hackish.  The clear advantage with Falstaff's code though is it will work for users that are on the free version of GLBasic.