我知道这是一个奇怪的事情,而且它不便携。但我有一个已分配的无符号整数数组,我偶尔想在其中“存储”一个浮点数。我不想转换浮点数或将其转换为最接近的等价的int;我想将float的精确位图存储在unsigned int的已分配空间中,这样我以后可以将它作为float检索,并保留其原始的float值。
答案 0 :(得分:6)
这可以通过简单的副本来实现:
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
向后复制的工作方式类似。
答案 1 :(得分:2)
只需重新解释相应的内存位置:
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的答案。
答案 2 :(得分:0)
如果你真的需要,你可以使用reinterpret_cast
。你甚至不需要像其他答案那样使用指针/地址。例如
int i;
reinterpret_cast<float&>(i) = 10;
std::cout << std::endl << i << " " << reinterpret_cast<float&>(i) << std::endl;
也有效(如果你很有意义,可以打印1092616192 10
;)。
编辑:
来自C ++标准(关于reinterpret_cast):
5.2.10.7指向对象的指针可以显式转换为指向不同类型对象的指针。除了转换为 “指向T1的指针”类型的rvalue到“指向T2的指针”类型(其中T1 和T2是对象类型,T2的对齐要求是 没有比T1更严格的并且回到原来的类型产生了 原始指针值,这种指针转换的结果是 未指定的。
5.2.10.10 10如果类型为“指向T1的指针”的表达式可以是类型T1的左值表达式,则可以将其转换为“对T2的引用”类型 使用a显式转换为“指向T2的指针”类型 reinterpret_cast的。也就是说,参考广告
reinterpret_cast<T&>(x)
与转换具有相同的效果*reinterpret_cast<T*>(&x)
内置&amp;和*运营商。结果是一个左值,它引用与源相同的对象 左值,但有不同的类型。没有临时创建,没有副本 制造,构造函数(12.1)或转换函数(12.3)不是 called.67)
因此,似乎一致地重新解释指针不是未定义的行为,并且使用引用与获取地址,重新预处理和引用获得的指针具有相同的结果。我仍然声称这不是未定义的行为。