#include <iostream>
#include <cstring>
#include <bitset>
using namespace std;
int main()
{
double tx = 0xFFFF0000FFFF0000;
uint64_t tx1 = 0;
static_assert(sizeof(double) == sizeof(uint64_t));
memcpy(&tx1, &tx, sizeof(double));
bitset<64> b1(tx1);
cout << b1 << endl;
return 0;
}
As I expected, the tx1
should be 0xFFFF0000FFFF0000
but b1
yields 0x43EFFFE0001FFFE0.
I'd like to know how to make b1
equal to 0xFFFF0000FFFF0000.
0xFFFF0000FFFF0000
is some integer value, but the important thing to note is that a 64 bit wide double
can only represent integers up to 53 bits. After that you just get the closest approximation.
When that happens, you now have some double
object of a value close to but not exactly 0xFFFF0000FFFF0000
.
You then std::memcpy
the double
representation back into an integer but since the double is no longer 0xFFFF0000FFFF0000
then neither will your integer.
Another thing to note is that floating point types and integer types have different binary representations. 42 in a double
does not have the same binary representation as 42
does in uint64_t
. This means that; no matter what, you'll never get the same bit pattern back out of the operation.
One thing you can do is use memcpy
both ways.
uint64_t start = 0xFFFF0000FFFF0000;
double tx;
uint64_t tx1;
memcpy(&tx, &start, sizeof(start));
// now `tx` is some value but it has the binary representation of 0xFFFF0000FFFF0000
memcpy(&tx1, &tx, sizeof(tx));
// now tx1 has the binary representation of 0xFFFF0000FFFF0000 since the bits never get changed