You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据整数符号进行左移或右移位操作?

支持正负移位计数的通用移位实现

宏定义方案(类型无关,兼容所有C标准)

直接通过条件判断选择左移或右移操作,无需提前知晓x的类型:

#define SHIFT(x, b) ((b) > 0 ? ((x) << (b)) : ((b) < 0 ? ((x) >> -(b)) : (x)))

细节说明

  • 当b=0时直接返回原数,符合无操作的需求;b>0执行左移,b<0取绝对值后执行右移。
  • 对于有符号类型的右移,C语言默认是算术右移(高位补符号位);如果需要逻辑右移(高位补0),可以先将x转为无符号类型:
    #define LOGICAL_SHIFT(x, b) ((b) > 0 ? ((x) << (b)) : ((b) < 0 ? ((unsigned)(x) >> -(b)) : (x)))
    
  • 必须保证|b|小于x类型的位数(比如32位int不能移32位及以上),否则属于未定义行为。

内联函数方案(C11+,更安全)

用_Generic适配不同整数类型,同时避免宏展开的副作用(比如x是表达式时重复计算):

#include <stdint.h>

static inline intmax_t shift_signed(intmax_t x, int b) {
    return b > 0 ? x << b : (b < 0 ? x >> -b : x);
}

static inline uintmax_t shift_unsigned(uintmax_t x, int b) {
    return b > 0 ? x << b : (b < 0 ? x >> -b : x);
}

#define SHIFT(x, b) _Generic((x), \
    intmax_t: shift_signed, \
    uintmax_t: shift_unsigned, \
    short: shift_signed, \
    unsigned short: shift_unsigned, \
    int: shift_signed, \
    unsigned int: shift_unsigned, \
    long: shift_signed, \
    unsigned long: shift_unsigned, \
    long long: shift_signed, \
    unsigned long long: shift_unsigned, \
    default: shift_signed((intmax_t)(x), b) \
)((x), (b))

优势

  • 自动区分有符号/无符号类型,匹配对应的移位逻辑;
  • 内联函数的形式减少了宏的潜在风险(比如参数重复求值)。

可选的安全校验

可以添加断言来确保移位计数在合法范围内,避免未定义行为:

#include <assert.h>
#define SHIFT(x, b) \
    (assert((b) >= -(int)(sizeof(x)*8) && (b) <= (int)(sizeof(x)*8)), \
    (b) > 0 ? ((x) << (b)) : ((b) < 0 ? ((x) >> -(b)) : (x)))

内容的提问来源于stack exchange,提问作者SRobertJames

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 07:32:21