我有一个unsigned long long(或uint64_t)值,想把它转换成一个double。这个双精度浮点数的位模式应该和long值的位模式相同。这样我就可以“手动”设置双精度浮点数的位。
unsigned long long
uint64_t
double
long
unsigned long long bits = 1ULL; double result = /* some magic here */ bits;
我正在寻找一种方法来做到这一点。
bxgwgixi1#
可移植的方法是使用memcpy(您也可以有条件地使用reinterpret_cast或联合体,但它们不一定是可移植的,因为它们违反了严格别名规则的字母):
memcpy
reinterpret_cast
// First, static assert that the sizes are the same memcpy(&result, &bits, sizeof(bits));
但是在你做之前,要确保你确切地知道你在做什么,以及使用什么浮点表示(尽管IEEE 754是一个流行的/常见的选择)。你会想避免各种各样的问题值,比如无穷大、NaN和非规格化数。
osh3o9ms2#
注意union和reinterpret_cast<double*>(&bits),因为这两个方法都是UB。几乎所有你能做的就是memcpy。
union
reinterpret_cast<double*>(&bits)
uz75evzq3#
从C++ 20开始,我们有std::bit_cast()到到这样转换例如:
std::bit_cast()
double d = 1.5; uint64_t i = std::bit_cast<uint64_t>(d); //use the same bits in an integer double dd = std::bit_cast<double>(i); //back to floating point again
jckbn6z74#
下面的代码使用了void指针。
unsigned long long bits = 1ULL; void* tempPtr=(void*)&bits; double result = *(double*)tempPtr;
4条答案
按热度按时间bxgwgixi1#
可移植的方法是使用
memcpy
(您也可以有条件地使用reinterpret_cast
或联合体,但它们不一定是可移植的,因为它们违反了严格别名规则的字母):但是在你做之前,要确保你确切地知道你在做什么,以及使用什么浮点表示(尽管IEEE 754是一个流行的/常见的选择)。你会想避免各种各样的问题值,比如无穷大、NaN和非规格化数。
osh3o9ms2#
注意
union
和reinterpret_cast<double*>(&bits)
,因为这两个方法都是UB。几乎所有你能做的就是memcpy。uz75evzq3#
从C++ 20开始,我们有
std::bit_cast()
到到这样转换例如:
jckbn6z74#
下面的代码使用了void指针。