为什么使用移位的此交换宏不适用于负数?

马特

我在内置库中找到了一些需要扩展的代码。

但它似乎已损坏:

#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有关。

如何修复此宏才能正常工作?

沙菲克·雅格莫(Shafik Yaghmour)

从草案C99标准部分的6.5.7 按位移位运算符表示(强调我的前进,向左移负数是不确定的行为

E1 << E2的结果是E1左移E2位的位置;空位用零填充。如果E1具有无符号类型,则结果的值为E1´2E2,与结果类型中可表示的最大值相比,模减少了1。如果E1具有带符号的类型和非负值,并且E1´2E2在结果类型中可表示,则这就是结果值;否则,行为是不确定的。

因此,的左移结果-8是不可预测的。强制转换为unsigned short应该可以解决以下问题:

BSWAP16((unsigned short)-8)

-8是一个整数常量(原),由于它没有后缀,因此它是一个int值,因为int可以采用它的值。假设32-bit int和twos补码将具有以下值:

 FFFFFFF8

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

右移负数也是实现定义:

E1 >> E2的结果是E1右移E2位的位置。如果E1具有无符号类型,或者E1具有带符号类型和非负值,则结果的值是E1 / 2E2商的整数部分。如果E1具有带符号的类型和负值,则结果值是实现定义的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么Hibernate HSQL Concat不适用于MSSQL?

为什么字符串concat宏不适用于这种“ +”情况?

为什么此正则表达式替换不适用于JavaScript,而仅适用于其他引擎?

为什么此扩展方法适用于泛型而不适用于设置的基本类型?

为什么此Bootstrap复选框不适用于jQuery?

了解此DNN模型以及为什么它不适用于多标签分类

使用列表推导查找变量可用于globals(),但不适用于locals()。为什么?

为什么此红宝石序列不适用于两位数数字?

为什么此代码不适用于特定类型的数据?

为什么此Dijkstra算法不适用于此特定输入?

Perl:为什么此表达式不适用于新版本的Perl?

为什么此Delegate约束不适用于定义事件?

为什么此string。标点符号代码不适用于剥离标点符号?

为什么此未定义检查不适用于查找功能?

为什么此jQuery验证不适用于IE 7/8?

为什么此数学运算不适用于宏?

算术移位不适用于负数输入?知道我在这里做错了吗?

为什么此仅用于数字输入的功能实际上不适用于输入类型:数字?

为什么此代码不适用于svg元素?

为什么此模式不适用于敲除验证?(分隔的邮政编码)

为什么此解决方案不适用于硬币找零算法?

为什么此过渡属性不适用于 css?

为什么此存储过程适用于一个查询而不适用于另一个?

是什么使此代码适用于 Y 轴而不适用于 X 轴?

为什么此查询不适用于指定的日期?

为什么我的函数适用于矩阵但为什么不适用于向量?

为什么此日志记录设置不适用于 INFO?

为什么此解决方案适用于 Javascript 而不适用于 Python?(动态编程)

为什么此 Java NaCl 加密不适用于 GitHub Actions Secrets