Little endian / Big endian

Previous topic - Next topic

Moru

I'm having troubles with converting unsigned longs from big endian to little endian format. Is there any bitwise shift command in GL-Basic? I'm using this code now but I can't convert numbers that end with a byte that starts with a 1 (binary).


Code (glbasic) Select
x = MSB_long(0xC8000000)
// x is supposed to be 200 after this call but the result you get is -128

FUNCTION MSB_long: number
LOCAL x1,x2,x3,x4

// Isolate the separate bytes
x1 = bAND(number, 0xff)
x2 = bAND(number, 0xff00) / 0x100
x3 = bAND(number, 0xff0000) / 0x10000
x4 = bAND(number, 0xff000000) / 0x1000000

// Add back the bytes in opposite order
number = 0
number = number + x1 * 0x1000000
number = number + x2 * 0x10000
number = number + x3 * 0x100
number = number + x4
RETURN number
ENDFUNCTION
what I want to do is just shift the bytes one at a time to the right instead of dividing by 0x1000000. If I do that he will think I'm dividing a negative value because of the first bit being set. Does anyone know of a better way to do this if there is no way of shifting bits?

Thunor

Well this should work but it doesn't :)
Code (glbasic) Select
FUNCTION MSB_long: number
    LOCAL x1,x2,x3,x4

    // Isolate the separate bytes
    x1 = bAND(number, 0xff)
    x2 = bAND(number / 0x100, 0xff)
    x3 = bAND(number / 0x10000, 0xff)
    x4 = bAND(number / 0x1000000, 0xff)

PRINT x1 + " " + x2 + " " + x3 + " " + x4 + " ", 100, 60

    // Add back the bytes in opposite order
    number = 0
    bOR(number, x1 * 0x1000000)
    bOR(number, x2 * 0x10000)
    bOR(number, x3 * 0x100)
    bOR(number, x4)

PRINT number, 100, 80

    RETURN number
ENDFUNCTION
It prints :-
0 0 0 200
0

And this prints the same :-
Code (glbasic) Select
FUNCTION MSB_long: number
    LOCAL x1,x2,x3,x4

    // Isolate the separate bytes
    x1 = bAND(number, 0xff) * 0x1000000
    x2 = bAND(number / 0x100, 0xff) * 0x10000
    x3 = bAND(number / 0x10000, 0xff) * 0x100
    x4 = bAND(number / 0x1000000, 0xff)

PRINT x1 + " " + x2 + " " + x3 + " " + x4 + " ", 100, 60

    // Add back the bytes in opposite order
    number = 0
    bOR(number, x1)
    bOR(number, x2)
    bOR(number, x3)
    bOR(number, x4)

PRINT number, 100, 80

    RETURN number
ENDFUNCTION
Gotta go to bed now...

Kitty Hello

OK, I've fixed this. It had to do with the most significant bit.

However: You're converting a number that's too big to be stored in a 32 bit float. Thus, when you port this program to PocketPC/GP2X, it _will not work_!
If you really must handle this big integers, please go for a wrapper using INLINE.

bigsofty

How difficult is it to add your own INLINE types Gernot? Also what should we look out for with regards to comparability with rest of the GLB Functions/System? Could you provide a simple example please?
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

Kitty Hello

I would use GLB types, but perform some INLINE action to convert/work with e.g. 32 bit integral types.
The whole problem usually comes from porting something from a different language to GLBasic. I never had problems of this kind before and I can't think of one out of my head now.
Why would one want to flip the endianess of a integer? Why can't you just store it correctly in the first place?
MAybe I'm missing some point here...

Moru

To be as general as possible because the format is written for non-intel systems. You can select big or little endian but default is the non-intel version so I need to be able to convert it.

Kitty Hello

Oh dear! GLBasic does the same, but goes the little endian (x86) way for READLONG and such.
I suggest writing a wrapper that uses readfile and reads single bytes. Then make a number from these.

Moru

ah, good idea, didn't think that far. Thanks!