Sign in to follow this  
Woody FX

Byte Arrays

Recommended Posts

I want to save some data to a byte array. I have a very simple way of doing it but notice some other people do it in a different way.

byte byte_array[10];

int x1=1;
int x2=2;
int x3=3;
int x4 = 4000;
int x5 = 50000;
long x6 = 600000;
int x7 = 700000;
int x8 = -1;
int x9 = -1000;
long x10 = -10000;

byte_array[0] = (byte)(x1);
byte_array[1] = (byte)(x2);
byte_array[2] = (byte)(x3);
byte_array[3] = (byte)(x4);
byte_array[4] = (byte)(x5) ;
byte_array[5] = (byte)(x6);
byte_array[6] = (byte)(x7) ;
byte_array[7] = (byte)(x8);
byte_array[8] = (byte)(x9);
byte_array[9] = (byte)(x10);


And an example of a co-workers code

for( int i = 0; i < GAMEMODES_LENGTH; i ++ )
    {
     for( int j = 0; j < GAMEMODES_SCORE_LENGTH; j ++ )
       {
        //score
        recordData[index++] = (byte) (0xff & (max_score[i][j] >> 24));
        recordData[index++] = (byte) (0xff & (max_score[i][j] >> 16));
        recordData[index++] = (byte) (0xff & (max_score[i][j] >> 8));
        recordData[index++] = (byte) (0xff & (max_score[i][j]));
        recordData[index++] = clear_level[i][j]; //lv
        recordData[index++] = max_combo[i][j]; //combo
       }
   }


Why does he use the bit shifts and the the binary AND ? Is he trying to save space and/or how exactly is it working? Is there a fault in the way i have filled my byte array and is there a better way? Thanks for the help! W

Share this post


Link to post
Share on other sites
The values like 50000 do not fit into a single byte, but into an int. So what your coworker does is to extract the binary representation of your value. If an int is 32 bits wide, and a byte just 8 bits, then you need 4 bytes to store the data that the int contains.

Share this post


Link to post
Share on other sites
So what he does is spread the int value over 4 bytes?

So he is breaking the value down with the bitshifts and then stores each part of the number in a seprate byte.


0xff &



What is the purpose of that?

Is there a website you can recommend that explain bytes the tricks people do on them?

Will google for some but if you know of a good one please share.

Thanks Brian

Share this post


Link to post
Share on other sites
Integer numbers are stored in two's-complement binary format. These numbers are grouped into blocks of 8 bits - bytes. In 32-bit systems, the size of a variable of type int is 32 bits, or 4 bytes.

A single byte in two's-complement can store numbers from -128 to 127. Adding additional bits expands the range. Any number that is less than -128 or greater than 127 cannot be stored in a single byte in two's-complement format. A 32-bit int, however, can store any number from –2,147,483,648 to 2,147,483,647.

As nmi said, your code will not work. By casting a number like, say, 4000 to a byte, you are forcing the compiler to ignore bits of the number that cannot be ignored. The result is that your number will come out as garbage.


In binary, specifically two's complement, 4000 is written 111110100000. We can break this up into bytes by selecting groups of four bits, starting at the right edge of the number:
00001111 | 10100000
Byte 1 Byte 2

Here you can see that it takes two bytes to represent 4000 in binary. You can play around with this yourself with the Windows calculator program by putting it in Scientific mode.

Your program already stores 4000 as a 32-bit int (4 bytes total). In order to make sure that all 4 bytes are kept in the byte array, your coworker's code is basically doing the same thing I did above: it splits the 4 bytes apart and stores them into the array. Because each element of the array is 1 byte, no single element can hold the whole 4-byte value.


If your compiler is worth anything, it will complain at you if you try to do this:

byte byte_array[10];
int x = 5000;
byte_array[0] = x;


It should warn you about loss of information or a similar type-conversion warning. Pay attention to these; ignoring them can lead to very bad bugs. Remember the golden rule of casts: if you see a type cast in code for integer numbers, you should immediately be suspicious of bad code. This is a royal P.I.T.A. in Java, because casting is required all over the place - but, of course, if you see Java, you should immediately be suspicious of bad code anyways [wink]

Share this post


Link to post
Share on other sites
Quote:
Original post by Woody FX
*** Source Snippet Removed ***

What is the purpose of that?

& is the bitwise AND operator. It goes bit-by-bit, and adds 1 if both bits are 1 otherwise it adds a 0.

0101
& 0001
------
0001

0xFF is 1111 1111, so it basically masks off everything except the low order byte.

CM

Share this post


Link to post
Share on other sites
I was trying to see if your coworker was trying to do endian-swapping, but no, he's just shoving a 32-bit value into an array of bytes.

Don't worry about learning from his example, what's he's doing is actually an inefficient way to achieve the goal, and could actually be made amazingly easier (to programmer, reader and compiler) by just using an array of structures.

Share this post


Link to post
Share on other sites
Using a structure is easier but then inevitably the standard question about structure packing comes up. Please see one of the eleventy-billion threads in this forum for discussions of structure packing issues.

The co-workers code is saving max_score as big-endian. That may or may not be significant. It also has the added touch of saving it un-aligned which could be an issue with non-x86 processors.

Share this post


Link to post
Share on other sites
We are(trying to) writing neutral code as the same code needs to be compiled in to Java and C (using a pre-processor for to handle the API specfic stuff from each platform) so maybe that and the fact we are extemely constrained by lack of memory is why his code is like it is.

I asked him why he is & 11111111 and he didnt seem 100% sure (maybe he felt i am saying that what he did was wrong) about why he did and that it is the way its done for Java.

The code is working so if it aint broke dont fix it(unless you are sure what you are doing).

Thanks guys,
W

Share this post


Link to post
Share on other sites
Quote:
Original post by Omaha
I was trying to see if your coworker was trying to do endian-swapping, but no, he's just shoving a 32-bit value into an array of bytes.

Don't worry about learning from his example, what's he's doing is actually an inefficient way to achieve the goal, and could actually be made amazingly easier (to programmer, reader and compiler) by just using an array of structures.


This is grossly incorrect as long as he keeps both load and save code in synch the code will run no matter endianness for both sender and reciviver putting it into a struct and passing that over the wire will cause problems down the line depending on endianess.

What they should be doing is utilzing the hton{s|l} and ntoh{s|l} functions to convert to/from local and network byteorder then put that in the array hopefully using helper functions instead of hardcoding it.

The code could be imensly simplified using some really simple helpers and still avoid both alignment and endianness issues I can give you that though :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this