繁体   English   中英

C++ 将 4 位 int_8t 转换为正常的 integer(32 位)

[英]C++ Bitshift 4 int_8t into a normal integer (32 bit )

我已经问过如何将 4 int8_t 转换为 32 位 int 的问题,有人告诉我必须先将 int8_t 转换为 uint8_t,然后通过位移将其打包为 32 位 integer。

int8_t offsetX = -10;
int8_t offsetY = 120;
int8_t offsetZ = -60;

using U = std::uint8_t;
int toShader  = (U(offsetX) << 24) | (U(offsetY) << 16) | (U(offsetZ) << 8) | (0 << 0);

std::cout << (int)(toShader >> 24) << " "<< (int)(toShader >> 16) << " " << (int)(toShader >> 8) << std::endl;

我的 Output 是

-10 -2440 -624444

当然,这不是我所期望的,有没有人有解决办法?

在着色器中,我想稍后解压 int16,这只能使用 32 位 integer,因为 glsl 没有任何其他数据类型。

 int offsetX = data[gl_InstanceID * 3 + 2] >> 24;
 int offsetY = data[gl_InstanceID * 3 + 2] >> 16 ;
 int offsetZ = data[gl_InstanceID * 3 + 2] >> 8 ;

方括号中写的内容无关紧要,它是关于位的正确移动或括号后的转换。

如果任何偏移量为负,则移位会导致未定义的行为。

解决方案:先将偏移量转换为无符号类型。

然而,这带来了另一个潜在问题:如果转换为unsigned ,那么负数将具有非常大的值,并且在最高有效字节中设置位,并且与这些位进行 OR 运算将始终得到 1,而不管offsetXoffsetY 一个解决方案是转换成一个小的无符号类型( std::uint8_t ),另一个是屏蔽未使用的字节。 前者可能更简单:

using U = std::uint8_t;
int third  = U(offsetX) << 24u
           | U(offsetY) << 16u
           | U(offsetZ) << 8u
           | 0u         << 0u;

我认为您忘记在移动之前屏蔽您关心的位。

也许这就是您要找的:

int32 offsetX = (data[gl_InstanceID * 3 + 2] & 0xFF000000) >> 24;
int32 offsetY = (data[gl_InstanceID * 3 + 2] & 0x00FF0000) >> 16 ;
int32 offsetZ = (data[gl_InstanceID * 3 + 2] & 0x0000FF00) >> 8 ;
if (offsetX & 0x80) offsetX |= 0xFFFFFF00;
if (offsetY & 0x80) offsetY |= 0xFFFFFF00;
if (offsetZ & 0x80) offsetZ |= 0xFFFFFF00;

如果没有位掩码,X 部分将在offsetY中结束,而 X 和 Y 部分将在offsetZ中结束。

在 CPU 端,您可以使用 union 来避免移位、位掩码和分支……

int8_t x,y,z,w; // your 8bit ints
int32_t i;      // your 32bit int

union my_union  // just helper union for the casting
 {
 int8_t i8[4];
 int32_t i32; 
 } a;

// 4x8bit -> 32bit
a.i8[0]=x;
a.i8[1]=y;
a.i8[2]=z;
a.i8[3]=w;
i=a.i32;

// 32bit -> 4x8bit
a.i32=i;
x=a.i8[0];
y=a.i8[1];
z=a.i8[2];
w=a.i8[3];

如果你不喜欢联合,同样可以用指针来完成......

当心 GLSL 方面这是不可能的(也不是联合或指针),你必须像其他答案一样使用位移和掩码......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM