[英]Turn two uint32_t into a uint64_t, then turn back into a double based on the bit pattern not the value
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.交给我两个 uint32_t 的代码本质上是一个双精度,二进制将它切成两半,所以一半的字节在一个变量中,另一半在另一个变量中。
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.这是我到目前为止所拥有的,它根本没有给出正确的 output。
it gives: 1.84467e+19 it should be: 6.49999999999999952595094363798E-11它给出:1.84467e+19 它应该是:6.49999999999999952595094363798E-11
Thanks谢谢
For C, you can do it this way:对于C,你可以这样做:
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.
我得到 6.5e-11 作为 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
.y
被转换为long long
,这意味着高位字是0xFFFFFFFF
。 x
and y
should be declared unsigned
. x
和y
应声明为unsigned
。static_cast
converts the value, not the bit pattern. static_cast
转换值,而不是位模式。 Use reinterpret_cast
to retain the bit pattern.reinterpret_cast
保留位模式。 (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.) std::bit_cast
。这不依赖于未定义的行为,只要double
和int64
相同尺寸。) 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双 d 2.300000e+01
int int64 4037000000000000 int int64 4037000000000000
double d 6.500000e-11双 d 6.500000e-11
int int64 3dd1ddf7e732a1b9 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.