对32位的无符号int的位进行操作的一些相关函数

我们有时候会用到对一个32位的位集合来进行操作,比如:
1.设置一个unsigned int 的某一位.
2.得到给定范围内1的个数.
3.把指定的值放入一个整型数里面保存起来,比如RGBA(红,绿,蓝,透明度),这四个参数的取值范围都是0-255,一个unsigned char 类型即可保存一个参数,我们可以用一个unsigned int 类型来保存这四个值。
上面的这些情况就需要使用到位操作,下面就是一些具体的操作和实现:

下面这些函数需要一个enum:

enum Formats {
    HALF_BYTE = 4,  
    BYTE = 8,
    HALF_WORD = 16,
    WORD = 32
};

这个函数可以在指定位置上面赋值,比如说我们可以把12这个数字放到uint32 current 的4-7位,那么current的位表现形式就为: Ox000000c0,再把15放到current的12-15位,那么current的表现形式就为:Ox0000f0c0.同样,我们也可以设置用8位,16位来保存我们需要的值。

/*
@parm target: 需要操作的数
@parm pos: 在第pos个位置上面进行操作
@parm format: 需要操作的位数(481632)
@parm value: 需要设置的值
出错返回0,正确返回修改过后的值的副本
*/

uint32_t setValueTo(uint32_t target,
uint32_t pos, Formats format, uint32_t value) {
    uint32_t tmp = pow(2, format) - 1;
    uint32_t max = 32 / format;
    if (pos < 0 || pos > max) {
        return 0;   
    }
    if (value > tmp) {
        return 0;
    }
    target &= ~(tmp << pos * format);
    return target |= (value << pos * format);
}

下面这个函数是上面函数的逆:得到指定位置的值:

/*
@parm target:需要操作的数
@parm pos:在第pos个位置上面进行操作
@parm format:需要操作的位数(481632)
出错返回0,正确返回修改过后的值的副本
*/

uint32_t getValueAt(uint32_t target, uint32_t pos, Formats format) {
    uint32_t max = 32 / format;
    if (pos < 0 || pos > max) {
        return 0;
    }
    uint32_t tmp = pow(2, format) - 1;
    target &= (tmp << pos * format);
    return (target >> pos * format);
}

下面这个函数可以用来把pos位置上面的位置为condition

/*
@parm target:需要操作的数
@parm pos:在第pos个位置上面进行操作
@parm condition:0 或者 1
出错返回0,正确返回修改过后的值的副本
*/
inline uint32_t switchBitCondition(uint32_t target, uint32_t pos, bool condition) {
    if (pos < 0 || pos > 31) {
        return 0;
    }
    if (condition) {
        return target |= condition << pos;
    }
    uint32_t tmp = 0xffffffff - (1 << pos);
    return target & tmp;
}

下面这个是得到pos位置上面的位(0 或 1) :

/*
@parm target:需要操作的数
@parm pos:在第pos个位置上面进行操作
出错返回-1,正确返回修改过后的值的副本
*/
inline int getBitCondition(uint32_t target, uint32_t pos) {
    if (pos < 0 || pos > 31) {
        return -1;
    }
    uint32_t tmp = 1;
    target &= (tmp << pos);

    return (target >> pos);
}

下面这个函数可以设置一段范围内的位:

/*
@parm target:需要操作的数
@parm begin: 需要设置位的开始索引
@parm end: 需要设置位的结束索引
出错返回0,正确返回修改过后的值的副本
*/
uint32_t setMultipleBitCondition(uint32_t target, uint32_t begin, uint32_t end, bool condition) {
    if (begin > end 
            || begin > 31
            || begin < 0
            || end > 31) {
        return 0;
    }

    if (begin == end) {
        return switchBitCondition(target, begin, condition);
    }

    uint32_t tmp = 1;
    if (condition) {
        for (uint32_t i = begin; i <= end; ++i) {
            target |= (tmp << i);
        }
    } else {
        for (uint32_t i = begin; i <= end; ++i) {
            target &= (tmp << i);
        }
    }
    return target;
}

下面这个函数得到一段范围里面位为1的个数:

/*
@parm target:需要操作的数
@parm begin: 需要搜索位的开始索引
@parm end: 需要搜索位的结束索引
返回修改过后的值的副本
*/
inline uint32_t countNumberOfOne(uint32_t target, uint32_t begin, uint32_t end) {
    uint32_t cnt = 0;
    for (uint32_t i = begin; i <= end; ++i) {
        int flag = getBitCondition(target, i);
        if (flag != -1 && flag != 0) {
            cnt++;
        }
    }
    return cnt;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值