Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flip bits using XOR 0xffffffff or ~ in C++?

If I want to flip some bits, I was wondering which way is better. Should I flip them using XOR 0xffffffff or by using ~?

I'm afraid that there will be some cases where I might need to pad bits onto the end in one of these ways and not the other, which would make the other way safer to use. I'm wondering if there are times when it's better to use one over the other.

Here is some code that uses both on the same input value, and the output values are always the same.

#include <iostream>
#include <iomanip>

void flipBits(unsigned long value)
{
    const unsigned long ORIGINAL_VALUE = value;
    std::cout << "Original value:" << std::setw(19) << std::hex << value << std::endl;

    value ^= 0xffffffff;
    std::cout << "Value after XOR:" << std::setw(18) << std::hex << value << std::endl;

    value = ORIGINAL_VALUE;
    value = ~value;
    std::cout << "Value after bit negation: " << std::setw(8) << std::hex << value << std::endl << std::endl;
}

int main()
{
    flipBits(0x12345678);
    flipBits(0x11223344);
    flipBits(0xabcdef12);
    flipBits(15);
    flipBits(0xffffffff);
    flipBits(0x0);
    return 0;
}

Output:

Original value:           12345678
Value after XOR:          edcba987
Value after bit negation: edcba987

Original value:           11223344
Value after XOR:          eeddccbb
Value after bit negation: eeddccbb

Original value:           abcdef12
Value after XOR:          543210ed
Value after bit negation: 543210ed

Original value:                  f
Value after XOR:          fffffff0
Value after bit negation: fffffff0

Original value:           ffffffff
Value after XOR:                 0
Value after bit negation:        0

Original value:                  0
Value after XOR:          ffffffff
Value after bit negation: ffffffff
like image 632
Programmer_D Avatar asked Dec 03 '22 18:12

Programmer_D


2 Answers

Use ~:

  • You won't be relying on any specific width of the type; for example, int is not 32 bits on all platforms.
  • It removes the risk of accidentally typing one f too few or too many.
  • It makes the intent clearer.
like image 159
Thomas Avatar answered Dec 14 '22 15:12

Thomas


As you're asking for c++ specifically, simply use std::bitset

#include <iostream>
#include <iomanip>
#include <bitset>
#include <limits>

void flipBits(unsigned long value) {
    std::bitset<std::numeric_limits<unsigned long>::digits> bits(value);
    std::cout << "Original value : 0x" << std::hex << value;

    value = bits.flip().to_ulong();
    std::cout << ", Value after flip: 0x" << std::hex << value << std::endl;
}

See live demo.

As for your mentioned concerns, of just using the ~ operator with the unsigned long value, and having more bits flipped as actually wanted:
Since std::bitset<NumberOfBits> actually specifies the number of bits, that should be operated on, it will well solve such problems correctly.

like image 31
πάντα ῥεῖ Avatar answered Dec 14 '22 15:12

πάντα ῥεῖ