我需要在 c 中从定点签名Q8 格式转换为定点签名Q4 格式。我假设我可以进行四位移位,这是正确的吗?我需要考虑符号位吗?
更新:这是针对 ARM11 架构的,但我更喜欢非架构特定的解决方案。
谢谢
移位应该可以工作,并且还可以处理许多架构上的符号位。在负数的情况下,更多的将被移入,但您要么只使用低 5 位,要么在 C 中进行算术运算,您需要这些额外的位来形成正确的二进制补码。
假设整数,代码将只是:
int q4 = q8 >> 4;
也许你想四舍五入:
int ahalf = q8 >= 0 ? (1<<3) : (1<<3)-1;
int q4 = (q8+ahalf) >> 4;
好的,我听了 Oli 的意见,并为不正确转换符号的架构提出了一个解决方案:
int q4 = q8 / (1<<4);
如果可能,优化器应将除法转换为班次。
通过四舍五入,第一个解决方案是
int ahalf = q8 >= 0 ? (1<<3) : -(1<<3);
int q4 = (q8+ahalf) / (1<<4);
感谢 R.. 的坚持,我终于测试了所有版本,现在它们在 Linux 下使用 Intel 32 位有符号整数产生了正确的结果。
我知道 C 的右移行为是实现定义的。见标准 6.5.7/5
(某些计算机可能会复制 MSB,如下图所示;其他计算机可能会添加“0”)
关心符号位看起来并不像很多工作。
但是,如果您的代码仅在同一台机器上编译,您可以检查该机器的实现,如果它“有效”则忽略符号位