如果该位在低和高之间,则将0位变为1位

时间:2017-01-29 18:38:51

标签: c bitwise-operators bit-shift

完全披露,这是一个家庭作业问题,我不需要确切的代码。我的任务是复制以下代码,同时只使用〜& +<<。

int result = 0;
int i;
for(i = lowbit; i <= highbit; i++)
    result |= 1 << i;
return result;

其中lowbithighbit031之间的参数。如果lowbit的数字大于highbit,则返回0。

我试过的是以下代码

int result = 0;
int negone = ~0x0;
int first = 1 << (lowbit + negone); //the first 1 bit is at the lowbit th location
int last = 1 << (highbit + negone); //the last 1 bit is at the highbit th location
int tick = ~(first + last); //attempting to get all bits in the range of low and highbit.
result = ~(~first & ~tick); //bitwise | without using |
result = ~(~last & ~result);
return result + 1; //the first bit should always be on.

那么我在这里缺少一些基本的东西吗?除了我没有工作的东西,这也超出了我允许使用的12个操作员的限制,但我想在我开始限制操作员之前尝试让它工作。

当我在此运行测试脚本时,我会在大多数测试中遇到错误,包括lowbithighbit彼此相等。 highbit是最大尺寸且lowbit的尺寸最小的情况似乎可以正常工作。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

negone应该以这种方式初始化:

uint32_t negone = ~0UL;

您正在使用位模式添加位号:

int first = 1 << (lowbit + negone); //the first 1 bit is at the lowbit th location
int last = 1 << (highbit + negone);

您应该改为计算32位掩码

uint32_t first = negone << lowbit;  // all bits below lowbit are 0, others are 1
uint32_t last = negone << highbit << 1;  // all bits above highbit are 1, other are 0

通过使用first

屏蔽last的补码来获得结果
uint32_t result = ~first & last;

结合上述步骤给出了7个运算符的直接解决方案(12个包括括号和赋值),没有加法,也没有减法:

uint32_t result = ~(~0UL << highbit << 1) & (~0UL << lowbit);

我使用0UL因为类型unsigned long保证至少有32位,而类型unsigned int可能只有16位。

答案 1 :(得分:1)

1)创建一个掩码,从低到高设置:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
  <select id="sms-from" ng-options="s for s in sms" ng-model="sendSms.from" ng-change="getVal(sendSms.from)">
</select>
</div>

示例:lowbit = 4,highbit = 12(9位)

uint32_t mask = ~(~0ul << highbit << 1) & (~0ul << lowbit)

2)将掩码应用于要修改的值,这最简单的是mask = ~(0xffffffff << 12 << 1) & (0xffffffff << 4) = ~(0xffff7000) & 0xfffffff0 = 0x00001fff & 0xfffffff0 = 0x00001ff0 操作,但这不是本练习中的有效运算符,因此必须使用De Morgan的论坛进行转换:

| - &gt; A|B

~(~A & ~B)

当然可以将这两个步骤结合起来,但也许不会提供清晰度。

答案 2 :(得分:0)

原始代码会在1之前生成lowbit块,直到highbit(含)。 这可以在没有循环的情况下实现,如下所示:

int nrOfBits = highbit + ~lowbit + 2;  // highbit - lowbit + 1
int shift = (nrOfBits & 0x1f + 1);
int result = ~(~(1 << shift)+1) << lowbit;

这个想法是,例如,用1填充的8位范围意味着255的数量,而2^8256。所以 - 由于操作符-不被允许,我们使用2-complement来获取-256,添加1来获取-255,然后将其转回+255使用2补码运算符~。然后,我们只需将块lowbits向左移动。

答案 3 :(得分:-1)

问题可能是dev_err()没有将位从低位翻转到高位。

也许我们可以这样做:

tick = ~(first+last)

这需要11位操作。

P.S。我想知道为什么第一位应该一直打开。

编辑:为了避免未定义的操作,我们应该使用无符号类型,如/* supposed that lowbit = 1, highbit = 2 */ uint32_t negone = ~(0u); /* negone = all 1s */ uint32_t first = negone << lowbit; /* first = ...111110 */ uint32_t last = (1 << (highbit + 1)) + negone; /* last = ...0000111 */ uint32_t tick = last & first; /* tick = ...000110 */ result = ~(~result&~tick); /* Bitwise Or without | as you mentioned. */