从0开始<六>:位运算符相关

本文介绍了三个位操作函数:getbits用于获取指定位置的位值;setbits用于设置指定位置的位值;invert用于求反指定位置的位值。通过具体的C语言实现展示了这些操作,并提供了一个测试程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序一:编写一个函数getbits(x,p,n),它将返回x中从右边数第p位开始向右边n位的字段,这里假定右边第一位是第0位,n和 p都是合理的正值

先看程序:(先把指定为移到最右边,然后再与1与,即取出来即可)

unsigned getbits(unsigned x, int p, int n)
{
	return (x >> (p+1-n)) & ~( ~0 << n);
}
问题一:什么叫n和p都为合理的正值 

答:即:p首先得在 unsigned 的范围内p+1-n>=0;

问题二:unsigned是什么类型

答:点击打开链接

程序二:编写一个函数setbits(x,p,n,y),该函数返回对x执行下列操作后的结果值:将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x中的其余各位保持不变

解释:先看后部分吧,后面的就是先取出y的最右边n位值,然后移动到p~(p+1-n)这个范围来,取出来的值,除了这个范围是与 y之前的相同外,其他的都是 0.

前面的就是把p~(p+1-n)这个范围都变为0就好,其他位不变,具体操作方法看程序就好,个人觉得这个每个人变换的方法不同。

unsigned setbits(unsigned x, int p, int n, unsigned y)
{
	return (x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) | ((y & ~(~0 << n)) << (p + 1 - n));
}

int main(void)
{
  unsigned i;
  unsigned j;
  unsigned k;
  int p;
  int n;
  
  for(i = 0; i < 30000; i += 511)
  {
    for(j = 0; j < 1000; j += 37)
    {
      for(p = 0; p < 16; p++)
      {
        for(n = 1; n <= p + 1; n++)
        {
          k = setbits(i, p, n, j);
          printf("setbits(%u, %d, %d, %u) = %u\n", i, p, n, j, k);
        }
      }
    }
  }
  return 0;
} 
问题一:测试程序有些奇怪

答:的确是,哈哈,我也不知道为啥。


程序三:编写一个函数invert(x,p,n),该函数返回对x执行下列操作后的结果值:将x中从第p为开始的n个(二进制)为求反(即,1变0,0变成1),x的其余各位保持不变。

思路:把需要改变的那部分与 1异或即可。

unsigned invert(unsigned x, int p, int n)
{
    return x ^ (~(~0U << n) << p);
}

#include <stdio.h>

int main(void)
{
  unsigned x;
  int p, n;

  for(x = 0; x < 700; x += 49)
    for(n = 1; n < 8; n++)
      for(p = 1; p < 8; p++)
        printf("%u, %d, %d: %u\n", x, n, p, invert(x, n, p));
  return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值