Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have some code below that is supposed to be converting a C (Arduino) 8-bit byte array to a 16-bit int array, but it only seems to partially work. I'm not sure what I'm doing wrong.

The byte array is in little endian byte order. How do I convert it to an int (two bytes per enty) array?

In layman's terms, I want to merge every two bytes.

Currently it is outputting for an input BYTE ARRAY of: {0x10, 0x00, 0x00, 0x00, 0x30, 0x00}. The output INT ARRAY is: {1,0,0}. The output should be an INT ARRAY is: {1,0,3}.

The code below is what I currently have:

I wrote this function based on a solution in Stack Overflow question Convert bytes in a C array as longs.

I also have this solution based off the same code which works fine for byte array to long (32-bits) array http://pastebin.com/TQzyTU2j.

/**
* Convert the retrieved bytes into a set of 16 bit ints
**/
int * byteA2IntA(byte * byte_slice, int sizeOfB, int * ret_array){

    //Variable that stores the addressed int to be stored in SRAM
    int currentInt;
    int sizeOfI = sizeOfB / 2;

    if(sizeOfB % 2 != 0) ++sizeOfI;
        for(int i = 0; i < sizeOfB; i+=2){
            currentInt = 0;
            if(byte_slice[i]=='\0') {
                break;
            }
            if(i + 1 < sizeOfB)
                currentInt = (currentInt << 8) + byte_slice[i+1];
            currentInt = (currentInt << 8) + byte_slice[i+0];
            *ret_array = currentInt;
            ret_array++;
        }
        //Pointer to the return array in the parent scope.
        return ret_array;
    }
share|improve this question
1  
Why don't you just cast to int* the pointer to the input array? –  icepack Nov 1 '12 at 11:39
 
What do you mean with "partially" work? What works, what doesn't? –  Olaf Dietsche Nov 1 '12 at 11:39
1  
@icepack int might be 4 bytes and he is converting 2 bytes to an int. –  Olaf Dietsche Nov 1 '12 at 11:41
1  
@AkiSuihkonen Might work, if short is 2 bytes and endianness permits. –  Olaf Dietsche Nov 1 '12 at 11:44
1  
@alk aa, I see what you mean. In this case using int is probably not the best choice and 16-bit type would suit better (something like AkiSuihkonen suggested) –  icepack Nov 1 '12 at 11:45
show 10 more comments

4 Answers

What is the meaning of this line of code?

if(i + 1 < sizeOfB) currentInt = (currentInt << 8) + byte_slice[i+1];

Here currentInt is always 0 and 0 << 8 = 0.

Also what you do is, for each couple of bytes (let me call them uint8_t from now on), you pack an int (let me call it uint16_t from now on) by doing the following:

  1. You take the rightmost uint8_t
  2. You shift it 8 positions to the left
  3. You add the leftmost uint8_t

Is this really what you want?

Supposing you have byte_slice[] = {1, 2}, you pack a 16 bit integer with the value 513 (2<<8 + 1)!

Also, you don't need to return the pointer to the array of uint16_t as the caller has already provided it to the function.

If you use the return of your function, as Joachim said, you get a pointer starting from a position of the uint16_t array which is not position [0].

share|improve this answer
 
I wrote this function based on this solution: stackoverflow.com/questions/11295728/… –  frazras Nov 1 '12 at 13:07
 
I also have this solution based off the same code which works fine for byte array to long(32-bits) array pastebin.com/TQzyTU2j –  frazras Nov 1 '12 at 13:13
 
@frazras Maybe you should clarify what you mean by "but it only seems to partially work" :)! –  Vincenzo Pii Nov 1 '12 at 13:17
 
I made the clarification in the question as an edit –  frazras Nov 1 '12 at 13:51
add comment

Vincenzo has a point (or two), you need to be clear what you're trying to do;

Combine two bytes to one 16-bit int, one byte being the MSB and one byte being the LSB

int16 result = (byteMSB << 8) | byteLSB;

Convert an array of bytes into 16-bit

for(i = 0; i < num_of_bytes; i++)
{
    myint16array[i] = mybytearray[i];
}

Copy an array of data into another one

memcpy(dest, src, num_bytes);

That will (probably, platform/compiler dependent) have the same effect as my 1st example.

Also, beware of using ints as that suggests signed values, use uints, safer and probably faster.

share|improve this answer
 
He said it is the first one... But your bitwise or is better than plus for sure –  texasbruce Nov 1 '12 at 14:29
 
Off to the opticians now... –  John U Nov 2 '12 at 11:54
add comment

The problem is most likely that you increase ret_array and then return it. When you return it, it will point to one place beyond the destination array.

Save the pointer at the start of the function, and use that pointer instead.

share|improve this answer
add comment

Consider using a struct. This is kind of a hack, though.

Off the top of my head it would look like this.

struct customINT16 {
    byte ByteHigh;
    byte ByteLow;
}

So in your case you would write:

struct customINT16 myINT16;

myINT16.ByteHigh = BYTEARRAY[0];
myINT16.ByteLow = BYTEARRAY[1];

You'll have to go through a pointer to cast it, though:

intpointer = (int*)(&myINT16);
INTARRAY[0] = *intpointer;
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.