用位运算实现有符号16bit数据clamp

在处理16 bit数据时,时常要将其他类型数据固定在16bit。

通常来说,在C语言中用一个if或者三目运算符就可以完成这个功能:

#define Limit16(a) ((a) > 0x7FFF ? 0x7FFF : ((a) < -0x8000 ? -0x8000 : (a)))

 

用位运算也可以巧妙实现此功能:

short clamp16(int sample)
{
    if ((sample >> 15) ^ (sample >> 31)) {
        sample = 0x7FFF ^ (sample >> 31);   
    }
    return sample;
}

 

代码流程说明如下:
  • 0 < sample <= 0x7FFF:
     sample >> 15 为 0;
     sample >> 31 为 0;
     异或后为0,跳过if,return sample;
  • sample > 0x7FFF:
     sample >> 15 为 1;
     这里的int假定为32位,sample >> 31 为 0;
     进入if后,sample = 0x7FFF ^ 0 = 0x7FFF;
  • -0x8000 <= sample < 0:
     sample >> 15 为 0xFFFFFFFF(高位为1,右移补1),负数是以补码的形式存在,大于-0x8000的数,高16位为1;
     sample >> 31 为 0xFFFFFFFF,异或为0;
     直接return
 
  • sample < -0x8000:
     sample >> 15 为0xFFFFxxxx低16位不确定,不全为1,sample >> 31 为 0xFFFFFFFF;
     异或后不为0,进入if;
     sample = 0x7FFF ^ 0xFFFFFFFF = 0xFFFF8000; 0xFFFF8000为其补码,值为-0x8000;
 
虽然这样的代码可能不便于阅读,不过作为一种位运算技巧,了解一下还是挺不错的。

转载于:https://www.cnblogs.com/speedracer/p/6928649.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值