user18348324
user18348324

Reputation: 262

How do I flip the bits of a double?

Consider this code:

#include <iostream>

int main(){
    double k = ~0.0;
    std::cout << k << "\n";
}

It doesn't compile. I want to get a double value with all the bits set, which would be a NaN. Why doesn't this code work, and how do I flip all the bits of a double?

Upvotes: 1

Views: 199

Answers (2)

HTNW
HTNW

Reputation: 29193

Regarding the code in the original question: The 0 here is the int literal 0. ~0 is an int with value -1. You are initializing k with the int -1. The conversion from int to double doesn't change the numerical value (but does change the bit pattern), and then you print out the resulting double (which is still representing -1).

Now, for the current question: You can't apply bitwise NOT to a double. It's just not an allowed operation, precisely because it tends not to do anything useful to floating point values. It exists for built in integral types (plus anything with operator~) only.

If you would like to flip all the bits in an object, the standard conformant way is to do something like this:

#include <memory>
void flip_bits(auto &x) {
  // iterate through bytes of x and flip all of them
  std::byte *p = reinterpret_cast<std::byte*>(std::addressof(x));
  for(std::size_t i = 0; i < sizeof(x); i++) p[i] = ~p[i];
}

Then

int main() {
  double x = 0;
  flip_bits(x);
  std::cout << x << "\n";
}

may (will usually) print some variation of nan (dependent on how your implementation actually represents double, of course).

Example on Godbolt

Upvotes: 2

robthebloke
robthebloke

Reputation: 9668

// the numeric constant ~0 is an integer
int foo = ~0;

std::cout << foo << '\n'; //< prints -1

// now it converts the int value of -1 to a double. 
double k = foo;

If you want to invert all of the bits you'll need to use a union with a uint64.

#include <iostream>
#include <cstdint>
int main(){

    union {
      double k;
      uint64_t u;
    } double_to_uint64;
    double_to_uint64.u = ~0ULL;
    std::cout << double_to_uint64.k;
}

Which will result in a -NAN.

Upvotes: 0

Related Questions