3

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;
    }
14
  • 1
    Why don't you just cast to int* the pointer to the input array? Commented Nov 1, 2012 at 11:39
  • What do you mean with "partially" work? What works, what doesn't? Commented Nov 1, 2012 at 11:39
  • 1
    @icepack int might be 4 bytes and he is converting 2 bytes to an int. Commented Nov 1, 2012 at 11:41
  • 1
    @AkiSuihkonen Might work, if short is 2 bytes and endianness permits. Commented Nov 1, 2012 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) Commented Nov 1, 2012 at 11:45

4 Answers 4

2

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].

Sign up to request clarification or add additional context in comments.

3 Comments

I wrote this function based on this solution: stackoverflow.com/questions/11295728/…
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 Maybe you should clarify what you mean by "but it only seems to partially work" :)!
2

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.

1 Comment

He said it is the first one... But your bitwise or is better than plus for sure
1

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.

Comments

1

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.