我有顶点作为float_3' s。我想为它们添加一个整数,然后将它们作为float_4' s发送出去。我不想将整数转换为具有相同值的浮点数,我需要的位完全相同(整数是一个存储桶xyz值位移位)。
以下是我的尝试:
void tagVerts (vector<float_3> &Verts, vector<float_4> &Output) {
int len = Verts.size();
for (int i = 0; i < len; i++) {
Output[i].xyz = Verts[i];
Output[i].w = reinterpret_cast<float>(XYZTag(Verts[i]));
}
}
它表示无效的类型转换:/
编辑: float_3和float_4来自amp.h,据我所知,它们只是一个带有一堆转换和赋值辅助函数的结构中的3或4个浮点数。
XYZTag如下:
int XYZTag(float_3 pos) {
pos = pos * mul + add;
int_3 posi (static_cast<int>(pos.x), static_cast<int>(pos.y), static_cast<int>(pos.z));
return((posi.x << 10) + posi.y << 10) + posi.z;
}
答案 0 :(得分:3)
您不能将int
的位解释为float
,因为这样做会违反strict aliasing rules,因此会调用未定义的行为。正确的方法是使用memcpy
复制位。
#include <cstring>
inline float
int_bits_to_float(const int bits)
{
static_assert(sizeof(int) >= sizeof(float), "too few bits");
float target;
std::memcpy(&target, &bits, sizeof(float));
return target;
}
乍一看似乎是一个糟糕的解决方案,我们真的希望编译器能够确定这可以优化到一些移动指令。即使在默认优化级别,GCC也会这样做。
答案 1 :(得分:0)
reinterpret_cast
不会将int
重新解释为float
,但可以重新解释指针。
int temp = XYZTag(Verts[i]);
Output[i].w = *reinterpret_cast<float*>(&temp);
// ^ ^ ^
这会将int
的确切位填充到float Output[i].w
中。您有责任确保这些类型的大小相同。
答案 2 :(得分:0)
您不能直接reinterpret_cast<>
int
。 static_cast<>
将无法满足您的需求。
要将位模式复制到另一种类型,您需要以下内容:
int val = 23;
float bitCopy = *reinterpret_cast<float*>(&val);
现在,要实现这一点,最好sizeof(float)
和sizeof(int)
相同。
此外,我们必须假设你知道自己在做什么才能想要这个。