bitset关于二进制运算

一、写在最前面

对于学习作业的记录,思考良多,还是不要面面俱到比较好。此后的博客都会只截取某一些部分进行个人思路的解说和注释,以便于重点突出。

二、关于bitset背景

建立一个表示32*5位的二进制数的5个int的集合,做到对各个位的检测、并且完成普通的二进制数能够完成的运算。

三、代码部分

1、对某一位的操作

这个函数是对整个数进行检测和取反操作的基础。原理在于对1进行移位,到对应位置时,运用二进制操作把对应的一位的数值取出,或者进行置1/置0操作。
以下是检测pos位是否为1的操作。这个函数可以被调用于所有对位操作的判断。

bool bitset::test(int pos) const{
    if(pos>max_length-1)
    return false;
    int count=1;
    if(a[pos/32] & (count<<(pos%32)))
    return true;
    return false;
}

以下就是对位进行值的改变。
获取掩码,还有进行的各种操作,都要熟悉。

void bitset::set(int pos){
    if(pos>max_length-1)
    return;
    int arr=pos/32;
    int bit=pos%32;
    int count=1;
    a[arr]|=count<<bit;
}
void bitset::reset(int pos){
    if(pos>max_length-1)
    return;
    int arr=pos/32;
    int bit=pos%32;
    int count=1;
    a[arr]&=~(count<<bit);
}

对1进行pos的位移,之前的思考是直接用2的幂来和原数进行操作。但是没有考虑到整数类型的溢出问题,可能会造成原来的int数与一个负数操作,结果就不可预估了。
有了这些对位的基本操作,其他的对某一位进行操作的函数都可以通过调用他们简单的实现了。

2、左移/右移操作

其他的操作的话,每一个int对应另一个bitset进行操作就可以,不再赘述。
左移右移的操作,其实困难就在于每个int的最高位要接收上一个int的最低位,而不是简单的做位移操作。对于这个,我的办法是用一个临时数组存储最低位的数值,在每个int做位移操作之后,再修改每一个int的最高位。

bitset& bitset::operator >>= (int pos){
    for(int i=0;i<pos;i++){
        int k=0;
        int temp[N-1]={0};//临时数组存每个int最低位是0/1
        for(k=0;k<N-1;k++){
            if(test(32*(k+1))){//判断最低位是0还是1 
            temp[k]=1;
            continue;
            }
            temp[k]=0;
        }
        for(k=0;k<N;k++){//所有int右移 
            a[k]>>=1;
        }
        for(k=0;k<N-1;k++){//把上个int最低位填到下个int最高位 
            if(temp[k]==0){
            reset(32*(k+1)-1);  
            }
            else
            set(32*(k+1)-1));
        }
    }
    return *this;
}

左移和右移的思想是完全相同的,以上是右移操作。左移就是把右边int的最高位最后填到左边int的最低位。

四、总结

对bitset这个类做记录,主要是自己对二进制的操作非常不熟悉。特别是对某一位的操作,以及左移右移的问题。面对这个由许多int拼接起来的二进制数,更加容易一脸蒙蔽。
首先,对于每一个位的操作,一是在于找准哪一位,二是在于如何得到掩码并进行操作,这些在网上都有资料,也很容易想清楚。
其次,左移右移的问题确实比较麻烦,同样要注意找准位的问题。还有对于基本的一位一位移动的思想,还是只是对最高最低位进行操作比较划算。
最后记录一下题目中的输出函数。其中思想就可以用于对整个二进制数进行遍历,可以对二进制数进行输出或者统计工作。

friend std::ostream& operator << (std::ostream& os, const bitset& s) {
            for (int i = N-1; i >= 0; i--) {
                for (int j = 31; j >= 0; j--) {
                    if (s.a[i] & (1 << j)) os << 1;
                    else os << 0;
                }
            }
            return os;
        }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值