0

In my personal C++ library, I code to handle working on different endian systems (little or big) by working with individual bytes. For example, I calculate a 16bit unsigned integer as follows by using a pointer, that points to the beginning of the uint16 data, as a parameter for my function:

constexpr uint16_t decode16(const uint8_t* x) {
    return uint16_t(x[1] + x[0] * 0x100);
}

As it is, this function doesn't work for a 16bit signed integer's byte data, and so 0xFF is decoded into -257. Can somebody please teach me how to write a similar function for signed integers that works? 0xFF should get decoded into -1.

Edit: This is my temporary solution which is a workaround for a little endian system, but won't be transportable onto a big endian system. What I'm looking for is how to code for both.

int16_t decode16(const int8_t* x) {
    int8_t temp8[2];
    temp8[0] = x[1];
    temp8[1] = x[0];
    int16_t temp16 = *(uint16_t *)&temp8[0];
    return temp16;
}
John Paoletto
  • 141
  • 2
  • 13
  • @500 - Internal Server Error, slightly different i believe because I'm dealing with signed integers, not unsigned – John Paoletto Jun 12 '19 at 14:48
  • Any of the bitshift operations in the linked question will work for you. But you also have to consider that the different platforms possibly have different signed integer representations, not just in terms of endian-ness (although there's a pretty high chance that it's 2's complement). – Balázs Kovacsics Jun 12 '19 at 15:11

1 Answers1

-1

Alright guys, so this is how I ended up doing it. Hope it helps anyone who likes to take a similar approach. Basically, bit by bit:

int16_t decode16(const int8_t* x) {
    std::bitset<8> firstbyte(x[0]);
    if (firstbyte[7] == 0) { // if positive integer, than treat as normal
        return int16_t(x[1] + x[0] * 0x100); 
    } else { // if negative integer, I assumed it's in Signed 2's Complement form (http://www.cs.umd.edu/~meesh/cmsc411/local-notes/numbers/node5.html)
        std::bitset<8> secondbyte(x[1]);
        std::bitset<16> tempset;
        // first copy all the bytes into a 16bit long bitset
        for (int i = 0; i < 16; i++) {
            if (i < 8) {
                tempset[i] = secondbyte[i];
            } else {
                tempset[i] = firstbyte[i-8];
            }
        }
        tempset.flip(); // then flip all bits

        // then add 1
        for (int i = 0; i < 16; i++) {
            if (tempset[i] == 0) {
                tempset[i] = 1;
                for (int j = (i-1); j>=0; j--) {
                    tempset[j] = 0;
                }
                break;
            }
        }

        int16_t answer = 0;
        for (int i = 0; i < 16; i++) {
            int16_t multiplier = 1;
            for (int j = 0; j<i; j++) {
                multiplier = multiplier*2;
            }
            answer = answer + tempset[i]*multiplier;
        }
        return answer*(-1);
    }
}
John Paoletto
  • 141
  • 2
  • 13