深入理解计算机系统第二版课后习题2.66

Write code to implement the following function:

/*

 *Generate mask indicating leftmost 1 in x.  Assume w=32.

 *For example 0xFF00 -> 0x8000, and 0x6600 -> 0x4000.

 * If x = 0, then return 0.

*/

int leftmost_one(unsigned x);

Your function should follow the bit-level integer coding rules(page 120), except that you may assume

that data type int has w=32 bits.

 Your code should contain a total of at most 15 arithmetic, bit-wise, and logical operations.

 Hint: Fisrt transform x into a bit vector of the form[0...011...1].

int leftmost_one(unsigned x)
{
    unsigned tmp;

    //构造从原始x最高位往右所有位都为1的无符号数
    tmp = x >> 1;
    x |= tmp;

    tmp = x >> 2;
    x |= tmp;

    tmp = x >> 4;
    x |= tmp;

    tmp = x >> 8;
    x |= tmp;

    tmp = x >> 16;
    x |= tmp;

    unsigned y,z;
    y = x + 1;
    z = y;
    y >>= 1;
    //倘若原始x最高位为31位
    z == 0 && (y = 0x8000);

    return y;
}

分析:
题目要求:为数A(0101)产生一个掩码M,A&M结果只保留A中最高位的1,即(0100)。所以(0100)就是A的掩码。

原理:若A为(0101 0101),若能得到B(0111 1111),则B+1得到C(1000 0000),然后C右移一位就可得到要求的掩码M(0100 0000)。

那么关键就是得到上述的B,若A为(0101 0101)(假设从右数第n位为最高位1):

           A  |  (A >> 1)  ---> B1(011* ****)  , 不管*代表0还是1,现在可得到第n,n-1位为1的数B1。

          B1 |  (B1>>2) --->B2(0111 1***),不管*代表0还是1, 现在可得到第n,n-1,n-2,n-3位为1的数B2.

          B2 | (B2>>4) ---->B3(0111 1111) , 此时,可得到B

显然,若A共w位,按上述过程,当Bi | (Bi>>w/2)一定可以得到B
有一个特殊情况,若A的最高位1恰好在w-1位上,得到的B就是(11......11)全1,这时候B+1得到C(00......00)全0,此时就用到

代码中

 z == 0 && (y = 0x8000),


即特殊情况下直接返回0x8000

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值