以前,我有以下C代码,通过该C代码,我希望在演员制作后将变量'sample'的签名扩展为'signed short '变量'sample_unsigned'。向左旋转和向右旋转以用于标志扩展(带符号短)C
unsigned short sample_unsigned;
signed short sample;
sample = ((signed short) sample_unsigned << 4) >> 4;
在二进制表示中,我期望'样本'有最重要的位重复4次。举例来说,如果:
sample_unsigned = 0x0800 (corresponding to "100000000000" in binary)
我明白了“样本”应该结果是:
sample = 0xF800 (corresponding to "1111100000000000" in binary)
然而,“样本”永远结束是一样的“sample_unsigned”,我不得不分割转让声明如下,哪些工作。为什么这个?
sample = ((signed short) sample_unsigned << 4);
sample >>= 4;
我知道右移的符号扩展会产生未定义的行为。我正在研究64位Ubuntu 12.04,在检查了我的gcc文档后,我决定尝试一下。我需要做这种操作的原因是因为我从一个提供10位有符号值的硬件平台捕获数据,后来我需要将其另存为ASCII。正如你所建议的,我猜想使用'uint16_t'和'int16_t'应该是一个更稳定的解决方案。 –
@CarlosCastro:我已经预料到了这种应用。我自己在嵌入式系统上使用它。只是不要依赖那个!上面的简单条件将不会在具有条件移动指令的平台上采用更多时钟(IIRC,x64确实提供了这样的功能,ARM明确做到这一点)。请注意,这是 - 像你问题中的代码 - 是12位有符号整数,而不是10位;所以你必须调整口罩!如果只是为了转换,可能会有更简单的技术。如果你可以节省内存空间,你甚至可以生成一个简单的查找表。 – Olaf
@CarlosCastro:我稍微更新了答案。如果答案有帮助,请随时注册。如果您需要最佳性能,只需对变体进行基准测试(但要小心**您实际测试的基准) – Olaf