Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2 Chars to Short in C

I've got 2 chars.

Char 128 and Char 2.

How do I turn these chars into the Short 640 in C?

I've tried

unsigned short getShort(unsigned char* array, int offset)
{
    short returnVal;
    char* a = slice(array, offset, offset+2);
    memcpy(&returnVal, a, 2);
    free(a);
    return returnVal;
}

But that didn't work, it just displays it as 128. What's the preferred method?

like image 602
Name McChange Avatar asked Jul 21 '13 02:07

Name McChange


3 Answers

Probably the easiest way to turn two chars, a and b, into a short c, is as follows:

short c = (((short)a) << 8) | b;

To fit this into what you have, the easiest way is probably something like this:

unsigned short getShort(unsigned char* array, int offset)
{
    return (short)(((short)array[offset]) << 8) | array[offset + 1];
}
like image 176
qaphla Avatar answered Nov 03 '22 01:11

qaphla


I found that the accepted answer was nearly correct, except i'd run into a bug where sometimes the top byte of the result would be 0xff...

I realized this was because of C sign extension. if the second char is >= 0x80, then converting 0x80 to a short becomes 0xff80. Performing an 'or' of 0xff80 with anything results in the top byte remaining 0xff.

The following solution avoids the issue by zeroing out the top byte of b during its implicit conversion to a short.

short c = (((short)a) << 8) | (0x00ff & b);
like image 35
fafrd Avatar answered Nov 03 '22 01:11

fafrd


I see that there is already an answer, but I'm a bit puzzled about what was going on with your original attempt. The following code shows your way and a technique using a union. Both seem to work just fine. I suppose you might have been running into an endianness problem. Anyway, perhaps this demonstration will be useful even if your problem is already solved.

#include <stdio.h>
#include <string.h>

int main()
{
    short returnVal;
    char a[2];
    union {
        char ch[2];
        short n;
    } char2short;

    a[0] = 128;
    a[1] = 2;

    memcpy(&returnVal, a, 2);

    printf("short = %d\n", returnVal);

    char2short.ch[0] = 128;
    char2short.ch[1] = 2;

    printf("short (union) = %d\n", char2short.n);

    return 0;
}

Outputs:

short = 640
short (union) = 640
like image 2
Nigel Avatar answered Nov 03 '22 02:11

Nigel