c语言 求32位数中最低非0位和最高非0位

一、最大非零位
这个原理和上一篇文章中将到的求fl的算法一样,通过对半查找之后再采用空间换时间的方式直接在一个数组中查找出相关值就可以了。代码参考如下:

int GetMaxOBit(int n) {
    int a;
    a = n <= 0xffff ? (n <= 0xff ? 0 : 8) : (n <= 0xffffff ? 16 : 24);
    return TLSF_Table[n >> a] + a;
}

或者

int Msb32(unsigned long Arg) {

 int RetVal = 0;

 if (Arg & 0xffff0000) { RetVal += 16; Arg &= 0xffff0000; }

 if (Arg & 0xff00ff00) { RetVal += 8; Arg &= 0xff00ff00; }

 if (Arg & 0xf0f0f0f0) { RetVal += 4; Arg &= 0xf0f0f0f0; }

 if (Arg & 0xcccccccc) { RetVal += 2; Arg &= 0xcccccccc; }

 if (Arg & 0xaaaaaaaa) RetVal += 1;

 return RetVal;

}


二、最小非零位
求一个数最小非零位的原理需要用到原码,补码,反码的知识,为了简单描述,假设是个一字节的数。为数字18为例,其二进制原码表示为“00010010”,记为a,为了表示-18,首先得出18的不包含符号位的反码是“1101101”,然后对其加1并添加上符号位,得出“11101110”,记为b,我们可以观察a和b的值,发现从低位开始直到第一个1是是相同的,其他的位都是相反的。所以实际上计算a&b,就得出值“00000010”,也就是说,将求一个数的最低非零位,就转变为了求其最高非零位。当然,也可以使用移位判断的方式求得最低有效位,但是显然,在嵌入式系统中,还是需要可以知道代码的确定执行时间的。代码参考如下:

int GetMinBit(int n) {
    int a = (int)n & (int)(-n);
    return GetMaxOBit(a);
}

三、某一位置1
这个比较简单,对1进行移位操作,知道1的位置到达需要置1的位置后,与原数进行或操作即可。代码参考如下:

int SetBit(int n,int a) {    
    if (n > 32){
        return a;
    } else {
        a |= (1<<n);
        return a;
    }
}

对超过32为的数置1的话,就不操作,返回原数即可。

四、某一位置0
对1进行移位操作,当1达到指定位置后,对这个数再进行取反操作,最后与原数进行与操作即可。代码参考如下:

int ClearBit(int n, int a) {
    if (n > 32){
        return a;
    } else {
        a &= ~(1<<n);
        return a;
    }
}

五、实验验证
整个代码如下:

#include <stdio.h>

static int TLSF_Table[256];

int GetMaxOBit(int n) {
    int a;
    a = n <= 0xffff ? (n <= 0xff ? 0 : 8) : (n <= 0xffffff ? 16 : 24);
    return TLSF_Table[n >> a] + a;
}

int GetMinBit(int n) {
    int a = (int)n & (int)(-n);
    return GetMaxOBit(a);
}

int SetBit(int n,int a) {    
    if (n > 32){
        return a;
    } else {
        a |= (1<<n);
        return a;
    }
}

int ClearBit(int n, int a){
    if (n > 32){
        return a;
    } else {
        a &= ~(1<<n);
        return a;
    }
}

main(){
    int i;
    int j = 0;
    int k = 0;
    TLSF_Table[0] = 0xffffffff;    
    for(i=2;i<=256;i=i*2,k++){
        for(;j<i;j++){
            TLSF_Table[j]=k;
        }
    }
    int a=460;
    int f1 = GetMinBit(a);
    printf("compute GetMinBit: %d\n",f1);
    
    int f2 = GetMaxOBit(a);
    printf("compute GetMaxOBit: %d\n", f2);
    
    int b = SetBit(9, a);
    printf("compute SetBit: %d\n",b);
    
    int c = ClearBit(7, a);
    printf("compute ClearBit: %d\n",c);

}
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值