gpt4 book ai didi

c - 向左旋转并向右旋转以使用 C 中的(带符号短)强制转换进行符号扩展

转载 作者:行者123 更新时间:2023-11-30 17:07:51 25 4
gpt4 key购买 nike

之前,我有以下 C 代码,通过该代码,我打算在强制转换为变量“sample_unsigned”的“signed Short”之后对变量“sample”进行符号扩展。

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”总是与“sample_unsigned”相同,我必须按如下方式拆分赋值语句,这有效。为什么会这样?

sample = ((signed short) sample_unsigned << 4);
sample >>= 4;

最佳答案

你的方法行不通。无法保证右移会保留该符号。即使如此,它也只适用于 16 位 int。对于 >=32 位 int ,您必须手动将符号复制到高位,否则它只会来回移动相同的数据。一般来说,有符号值的位移位至关重要 - 有关详细信息,请参阅[标准]( http://port70.net/~nsz/c/c11/n1570.html#6.5.7。某些星座会调用未定义的行为。最好避免它们并仅使用无符号整数。

但是,对于大多数平台,以下方法都有效。它不一定更慢(在 16 位 int 平台上,它可能更快):

uint16_t usample;
int16_t ssample;

ssample = (int16_t)usample;
if ( ssample & 0x800 )
ssample |= ~0xFFF;

转换为int16_t是实现定义的;您的编译器应指定它是如何执行的。对于(几乎?)所有最近的实现,没有执行额外的操作。只需在生成的代码或编译器文档中进行验证即可。逻辑或依赖于使用 2 补码的 intX_t,这是由标准保证的 - 而不是标准类型。

在 32 位平台上,可能存在用于符号扩展的内在指令(例如 ARM Cortex-M3/4 SBFX)。或者编译器提供了一个内置函数。根据您的用例和速度要求,可能适合使用它们。

更新:

另一种方法是使用位域结构:

struct {
int16_t val : 12; // assuming 12 bit signed value like above
} extender;

extender.val = usample;
ssample = extender.val;

这可能会导致使用我上面建议的相同汇编器指令。

关于c - 向左旋转并向右旋转以使用 C 中的(带符号短)强制转换进行符号扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33960826/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com