[英]opengl c++: How to convert a 32bit png file to a 16 bit 565RGB file
[英]Compound operator with shift in C or how to convert 20bit 2'complement number in 32bit signed int
有20位2'补数(用3 x 8位读取),需要转换成32位有符号整数。
有人可以解释一下这段代码:
int32_t sample = 0;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
sample <<= 8;
sample /= 1L << 12;
所以现在在 32 位签名 integer 从右边开始有 24 个值然后:
sample /= 1L << 12;
这是如何工作的?
完整代码的链接位于:
https://github.com/circuitar/Nanoshield_LoadCell/blob/master/src/Nanoshield_LoadCell.cpp
通常,应在无符号 integer 类型上执行按位移位操作,因为:
如果您小心避免上述所有情况,则可以在带符号的 integer 类型上可移植地使用按位移位操作,如下面的1所示:
int32_t sample = 0;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
sample >>= 4;
// 'sample' contains a 20-bit, 2's complement value. Sign-extend to a 32-bit signed value.
if (sample >= (INT32_C(1) << 19))
sample -= (INT32_C(1) << 20);
if (sample >=...
符号扩展部分可能不是无分支的,具体取决于编译器。从 20 位 2 的补码到 32 位符号的替代符号扩展转换是:
sample = (sample ^ (INT32_C(1) << 19)) - (INT32_C(1) << 20);
XOR 运算将 2 的补码值转换为偏移二进制值。 该操作可以合并到来自第一个 SPI 传输的字节值(20 位样本值的最高有效 8 位),如下所示:
int32_t sample = 0;
sample |= SPI.transfer(0) ^ 0x80; // convert 2's complement to offset binary
sample <<= 8;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
sample >>= 4;
// 'sample' contains a 20-bit, offset binary value. Convert to 32-bit, signed value.
sample -= INT32_C(1) << 20;
1只要实现提供了int32_t
,这里的“可移植”就可以了。 如果不是,则可以改用int_least32_t
。
这是如何工作的?
如果SPI.transfer(0)
返回 0-255,则当 20 位数字位于读取数据的高 24 位时,它“有效”。 然后将其转换为 32 位类型的符号位依赖于 UB 来形成正确的值,当除法时1 << 12
是寻求的值。
要将 20 位 2 的补码数转换为int32_t
,请测试符号位。
// Alternative without UB nor implementation defined behavior:
int32_t sample = 0;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
sample <<= 8;
sample |= SPI.transfer(0);
// if input is in upper 20 bits of the 24 read (OP is not explicit on that)
if (1) {
sample >>= 4;
}
assert(sample >= 0 && sample <= 0xFFFFF);
if (sample & 0x80000) { // Test for the 20-bit 2's complement sign bit
sample -= 0x100000;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.