the code that hands me the two uint32_t essentially takes a double, in binary cuts it in half so half the bytes are in one variable and the other half are in the other.
My program need to take them and stitch it back together.
int x = 0b00111101110100011101110111110111;
int y = 0b11100111001100101010000110111001;
uint64_t int64 = (long long) x << 32 | y;
double d = static_cast<double> (int64);
this is what i have so far and it doesnt give the correct output at all.
it gives: 1.84467e+19 it should be: 6.49999999999999952595094363798E-11
Thanks
For C, you can do it this way:
const uint32_t x = 0x3DD1DDF7;
const uint32_t y = 0xE732A1B9;
const uint64_t z = ((uint64_t) x << 32) | y;
double d;
memcpy(&d, &z, sizeof d);
But I'm not sure, there could be an endian issue here since this code is quite hairy. I'm getting 6.5e-11 as the output.
This works:
unsigned int x = 0b00111101110100011101110111110111;
unsigned int y = 0b11100111001100101010000110111001; // Must be unsigned!
uint64_t int64 = ((long long) x << 32) | y; // Parentheses highly recommended for
// readability (but not strictly necessary)
double d = reinterpret_cast<double&> (int64); // Definitely not portable!
Your code had two problems:
y
was being converted to long long
, which meant that the high word was 0xFFFFFFFF
. x
and y
should be declared unsigned
. static_cast
converts the value, not the bit pattern. Use reinterpret_cast
to retain the bit pattern. (As Mgetz points out in a comment, there is now (since C++20) an official way to get this done: std::bit_cast
. This doesn't rely on undefined behaviour, as long as double
and int64
are the same size.) How about this code for your purpose. example
#include <cstdio>
#include <cinttypes>
#include <type_traits>
#include <cstddef>
#include <iostream>
int main()
{
uint64_t tsc = 0xdeaddeadc0dec0de;
uint32_t MSB = *((uint32_t*)&tsc+1);
uint32_t LSB = *((uint32_t*)&tsc);
std::printf("low %x high %x \n", LSB,MSB);
uint64_t MLSB = 0;
*((uint32_t*)&MLSB) = LSB;
*((uint32_t*)&MLSB+1) = MSB;
std::printf("highlow %lx \n", MLSB);
uint64_t LMSB = 0;
*((uint32_t*)&LMSB+1) = LSB;
*((uint32_t*)&LMSB) = MSB;
std::printf("lowhigh %lx \n", LMSB);
}
solution to your problem
#include <cstdio>
#include <cinttypes>
#include <type_traits>
#include <cstddef>
#include <iostream>
int main()
{
int x = 0b01000000001101110000000000000000;
int y = 0b00000000000000000000000000000000;
uint64_t int64 = 0;
*((uint32_t*)&int64+1) = x;
*((uint32_t*)&int64) = y;
double d = *((double*)&int64);
std::printf("double d %e \n", d);
std::printf("int int64 %llx \n", int64);
x = 0b00111101110100011101110111110111;
y = 0b11100111001100101010000110111001;
*((uint32_t*)&int64+1) = x;
*((uint32_t*)&int64) = y;
d = *((double*)&int64);
std::printf("double d %e \n", d);
std::printf("int int64 %llx \n", int64);
}
result
double d 2.300000e+01
int int64 4037000000000000
double d 6.500000e-11
int int64 3dd1ddf7e732a1b9
or without referencing problem
#include <cstdio>
#include <cinttypes>
#include <type_traits>
#include <cstddef>
#include <iostream>
int main()
{
unsigned char x[] = {0b01000000,0b00110111,0b00000000,0b00000000};
unsigned char y[] = {0b00000000,0b00000000,0b00000000,0b00000000};
uint64_t int64 = 0;
*((unsigned char*)&int64+7) = x[0];
*((unsigned char*)&int64+6) = x[1];
*((unsigned char*)&int64+5) = x[2];
*((unsigned char*)&int64+4) = x[3];
*((unsigned char*)&int64+3) = y[0];
*((unsigned char*)&int64+2) = y[1];
*((unsigned char*)&int64+1) = y[2];
*((unsigned char*)&int64+0) = y[3];
double d =0;
*((unsigned char*)&d+7) = x[0];
*((unsigned char*)&d+6) = x[1];
*((unsigned char*)&d+5) = x[2];
*((unsigned char*)&d+4) = x[3];
*((unsigned char*)&d+3) = y[0];
*((unsigned char*)&d+2) = y[1];
*((unsigned char*)&d+1) = y[2];
*((unsigned char*)&d+0) = y[3];
//*((double*)&int64);
std::printf("double d %e \n", d);
std::printf("int int64 %lu \n", int64);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.