gpt4 book ai didi

c - 为什么这个使用移位的交换宏不适用于负数?

转载 作者:行者123 更新时间:2023-12-01 15:33:11 24 4
gpt4 key购买 nike

我在一个内置的库中找到了一些我已经拥有并且需要扩展的代码。

但它似乎坏了:

#define BSWAP16(__x)    ((((__x) >> 8) | ((__x) << 8)))

功能不同于:

__builtin_bswap16()

这个程序证明了这一点。

#include <stdio.h>

#define BSWAP16(__x) ((((__x) >> 8) | ((__x) << 8)))

int main(int argc, char* argv[])
{
unsigned short a = (unsigned short)BSWAP16(0xff00);
unsigned short b = __builtin_bswap16(0xff00);
short c = (short)BSWAP16(-8);
short d = __builtin_bswap16(-8);

printf("a=%04x, b=%04x, c=%04x, d=%04x\n", a,b,c,d);
return 0;
}

输出:

a=00ff, b=00ff, c=ffffffff, d=fffff8ff

我不想得到告诉我应该使用 endian.h 或 __builtin_bswap16 的答案。在此平台/编译器配置上,此内部库使用的目标平台上,我正在触发默认使用上述宏的默认代码。

所以我的问题是。为什么它不适用于负数?

如果我将 -8 表示为 0xfff8 的短值,它就可以工作。

所以我猜它与内部转换为 int 有关。

如何修复此宏以使其正常工作?

最佳答案

左移一个负数是未定义的行为,来自草案 C99 标准部分 6.5.7 位移运算符 说(强调我的前进):

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 ´ 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 ´ 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

所以-8左移的结果是不可预测的。转换为 unsigned short 应该可以解决问题:

BSWAP16((unsigned short)-8)

-8 是一个整数常量(文字)并且因为它没有后缀将是一个 int 因为 int 可以承担它的值(value)。假设 32 位 int 和二进制补码将具有以下值:

 FFFFFFF8

转换为 unsigned short 将删除不需要的高位。转换为 unsigned int 无济于事,因为它会保留较高的位。

右移负数也是实现定义的:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

关于c - 为什么这个使用移位的交换宏不适用于负数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24565837/

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