我知道这是一件奇怪的事情,而且它不能移植。但是我有一个分配的无符号整数数组,有时我想在其中“存储”一个浮点数。我不想强制转换浮点数或将其转换为最接近的等效整数;我想将浮点数的精确位图像存储在无符号整数的分配空间中,这样以后我就可以将其作为浮点数检索,而它将保留其原始的浮点值。
发布于 2011-12-03 03:11:11
这可以通过简单的复制来实现:
uint32_t dst;
float src = get_float();
char * const p = reinterpret_cast<char*>(&dst);
std::copy(p, p + sizeof(float), reinterpret_cast<char *>(&src));
// now read dst
向后复制的工作原理与此类似。
发布于 2011-12-03 03:04:02
只需对相应的内存位置进行重新解释转换:
float f = 0.5f;
unsigned int i = *reinterpret_cast<unsigned int*>(&f);
或者更像C语言的版本:
unsigned int i = *(unsigned int*)&f;
从你的问题文本中,我假设你已经意识到,如果float
和unsigned int
的大小不同,这就会中断,但在大多数常见的平台上,两者都应该是32位的。
编辑:正如Kerrek所指出的,这似乎是一种未定义的行为。但我仍然坚持我的答案,因为它是简短和精确的,并且确实应该在任何实际的编译器上工作(说服我相反的)。但是,如果你想要一个无UB的答案,请看看Kerrek的答案。
发布于 2011-12-03 03:53:46
如果真的有必要的话,你可以使用reinterpret_cast
。你甚至不需要像其他答案提到的那样玩弄指针/地址。例如
int i;
reinterpret_cast<float&>(i) = 10;
std::cout << std::endl << i << " " << reinterpret_cast<float&>(i) << std::endl;
也可以工作(如果您是qurious,还会打印1092616192 10
;)。
编辑:
来自C++标准(关于reinterpret_cast):
5.2.10.7指向对象的指针可以显式地转换为指向不同类型的对象的指针,将“指向T1的指针”类型的右值转换为“指向T2的指针”类型(其中T1和T2是对象类型,其中T2的对齐要求不比T1的对齐要求更严格),并返回到其原始类型产生原始指针值,这种指针转换的结果未指定。
5.2.10.10如果“指向T1的指针”类型的表达式可以使用reinterpret_cast显式转换为“指向T1的指针”类型,则可以将类型为T2的左值表达式转换为“指向T2的引用”类型。也就是说,使用内置的&和*运算符,引用类型转换reinterpret_cast<T&>(x)
与转换*reinterpret_cast<T*>(&x)
具有相同的效果。结果是一个左值,它引用与源左值相同的对象,但具有不同的类型。不创建临时函数,不创建副本,不调用构造函数(12.1)或转换函数(12.3)。67)
因此,似乎一致地重新解释指针并不是未定义的行为,并且使用引用具有与获取地址、重新解释和延迟获得的指针相同的结果。我仍然认为这不是未定义的行为。
https://stackoverflow.com/questions/8365143
复制