Thread: Two's Compiment

  1. #1
    Registered User
    Join Date
    Aug 2013
    Posts
    40

    Two's Compiment

    I had a bunch of 8bit packets I had to separate into opcode and operand. I have pulled out the first 2 bits for the opcode and I have the 6 bit operand saved to a Int.

    I need to be able to work with negative number in two's compliment. Is there a quick way I can convert the 6 bit operand from twos compliment into a negative Integer?

    So it would convert 34 into -30. I can detect the sign at the beginning with a bit mask. but from there I'm lost.

  2. #2
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Two's Complement

    Code:
    #include <stdio.h>
    
    int six_bit_sign_extend(unsigned char b) {
        b &= 0x3f; // ensure b is less than 64
        return b < 32 ? b : 64 - b;
    }
    
    int main() {
        unsigned char b = 34;
        printf("%d\n", six_bit_sign_extend(b));
        return 0;
    }

  3. #3
    Registered User
    Join Date
    Aug 2013
    Posts
    40
    Nice one thanks... I must have tried about 4 different methods and each one didnt work.

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    I made a mistake. The sign needs to be reversed:
    Code:
    #include <stdio.h>
    
    int six_bit_sign_extend(unsigned char b) {
        b &= 0x3f; // ensure b is less than 64
        return b < 32 ? b : b - 64;
    }
    
    int main() {
        unsigned char b = 34;
        printf("%d\n", six_bit_sign_extend(b));
        return 0;
    }

  5. #5
    Registered User cstryx's Avatar
    Join Date
    Jan 2013
    Location
    Canada
    Posts
    123
    Or for a different approach:
    Code:
    int six_bit_sign_extend(unsigned char b) {
        b &= 0x3f;
        return b & 0x20 ? b | ~0x3f : b;
    }
    Last edited by cstryx; 11-23-2016 at 05:20 PM.

  6. #6
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Or if you wanted to avoid the conditional:
    Code:
    int six_bit_sign_extend(unsigned char b) {
        unsigned char s = b & 0x20; // sign bit
        return (signed char)(s << 1 | s << 2 | (b & 0x3f));
    }
    Looking up the bit-twiddling hack yields this:
    Code:
    int six_bit_sign_extend(unsigned char b) {
        struct {signed int b: 6;} s;
        return s.b = b;
    }
    Last edited by algorism; 11-23-2016 at 07:15 PM.

Popular pages Recent additions subscribe to a feed

Tags for this Thread