Search code examples
binaryunsignedbittwos-complement

How do I find the minimum number of bits for unsigned magnitude and 2's compliment?


I am slightly confused about finding the minimum number of bits for an unsigned magnitude and 2's compliment. This has been my reasoning so far: For example,

a) 243 decimal
Since 2^8 = 256, Unsigned and 2's compliment would both need a minimum 8 bits.
b) -56 decimal
This is impossible for unsigned.
2^6 = 64. One more bit is needed to show it is negative, so minimum 7 bits.

Is my reasoning correct?


Solution

  • The "bits needed" for unsigned is just the most significant bit (+1, depending on the definition for MSB), and for two's complement you can just negate the value and subtract one to make it positive, then add another bit for the sign flag.

    int LeadingZeroCount(long value) {
        // http://en.wikipedia.org/wiki/Hamming_weight
        unsigned long x = value;
        x |= (x >> 1); x |= (x >> 2); x |= (x >> 4);
        x |= (x >> 8); x |= (x >> 16); x |= (x >> 32);
        x -= (x >> 1) & 0x5555555555555555;
        x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
        x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F;
        x += x >> 8; x += x >> 16; x += x >> 32;
        return (sizeof(value) << 3) - (x & 0x7F);
    }
    
    int MostSignificantBit(long value) {
        return (sizeof(value) << 3) - LeadingZeroCount(value);
    }
    
    int BitsNeededUnsigned(unsigned long value) {
        return MostSignificantBit(value);
    }
    
    int BitsNeededTwosComplement(long value) {
        if (value < 0)
            return BitsNeededUnsigned(-value - 1) + 1;
        else
            return BitsNeededUnsigned(value);
    }
    
    int main() {
        printf("%d\n", BitsNeededUnsigned(243));
        printf("%d\n", BitsNeededTwosComplement(243));
        printf("%d\n", BitsNeededTwosComplement(-56));
        return 0;
    }
    

    That's based on your definition of the problem, at least. To me it seems like +243 would need 9 bits for two's complement since the 0 for the sign bit is still relevant.