int has more than tree bits, so you must mask the result of a bitwise negation like this:
int flip(int n) { // bitwise AND with 0b111 = 7, this will clear all but the last 3 bits return ~n & 0b111; }
The reason you got -6 is because int is typically represented in two's complement, where -6 is all 1-bits but ends with 010. You must remove these leading 1-bits to get the correct result.
Generally, I would recommend not using bitwise operations with signed numbers and instead do the following:
unsigned flip(unsigned n) { return ~n & 0b111; } // this version works with any number of bits, not just 3 unsigned flip(unsigned n, unsigned bits) { unsigned mask = (1 << bits) - 1; return ~n & mask; }
If you don't know how many bits your number has, you must first find the most significant bit. In the most naive way, it can be done like this:
unsigned log2(unsigned val) { unsigned result = 0; while (val >>= 1) { ++result; } return result; } unsigned variable_flip(unsigned n) { return flip(n, log2(n)); }
You can find more efficient solutions here.
For example:
unsigned log2_debruijn(uint32_t val) { static const unsigned MultiplyDeBruijnBitPosition[32] = {0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31}; // first round down to one less than a power of 2 // this step is not necessary if val is a power of 2 val |= val >> 1; val |= val >> 2; val |= val >> 4; val |= val >> 8; val |= val >> 16; return MultiplyDeBruijnBitPosition[(val * uint32_t{0x07C4ACDD}) >> 27]; }
inthas more than 3 bits. One of them happens to be the sign-bit as you correctly guessed. What is "the perfect way to implement the operation"? Do you want to implement bitwise not yourself? What operation do you want to implement and what is not perfect now?n = 5contains a load of leading zeros (the number depends on the size of yourint). You are setting those leading zeros to 1 in your output.~operator. You'll also need to be careful on handling the sign bit (elements of unspecified or implementation-defined [don't recall which offhand] behaviour on negative values). Also, unlike~, it means that applying your approach twice won't necessarily give back the original value (101->010->001).