zoukankan      html  css  js  c++  java
  • 《C程序设计语言》 练习2-6 及 位运算总结

    问题描述

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

      Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.

    知识点复习

      1.按位与运算符(&)

        参加运算的两个数据,按二进制位进行“与”运算

        运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1;  (两位同时为“1”,结果才为“1”,否则为0)

          例如: 2 & 3 

        换为二进制:0000 0010 & 0000 0011 = 00000010

        所以2 & 3 = 2

        (负数按补码形式参与按位与运算)

       2.按位或运算符( | )

        参加运算的两个对象,按二进制位进行“或”运算。

        运算规则:0|0=0;  0|1=1;  1|0=1;   1|1=1;(参加运算的两个对象只要有一个为1,其值为1)

        例如:2 | 3 

        换位二进制: 0000 0010 | 0000 0011 = 0000 0011

          所以2 | 3 = 3 

        (负数按补码形式参加按位或运算)

       3.异或运算符( ^ )

        参加运算的两个数据,按二进制位进行“异或”运算。

        运算规则:0^0=0;  0^1=1;  1^0=1;   1^1=0;(参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0)

        例如:2 ^ 3

        换为二进制:0000 0010 ^ 0000 0011 = 0000 0001

        所以2 ^ 3 = 1

        异或运算符有一条有趣的性质,自反性:a ^ b ^ b = a

        利用这条性质,我们可以不用借助第三个变量,实现两个数值的交换

        例如交换a和b的值:

        

    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    

        解释一下这个代码:

        第一句:令a = a^b

        第二局:b=a^b,其中的a用第一句的的等式替换 b = a^b^b=a

        第三句同理,a = a^b=a^a^b=b

       4.左移运算符(<<)
        将一个运算对象的各二进制位全部左移若干位,左边的二进制位丢弃,右边补0

        例:0000 0011<<2 = 0000 1100 左移2位,右补0

        若左移时舍弃的高位不包含1,则每左移一位,相当于该数十进制下乘以2

       5.右移运算符(>>)
        将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃

        操作数每右移一位,相当于该数十进制除以2

        左补0 or 补1得看被移数是正还是负

    解题步骤

        这里我们直接用一个例子来解释这道题目:

        假设 setbits(93 , 4 , 3 , 211)

        93二进制:1 0 1 1    1 0 1

        211二进制:1 1 0 1    0 0 1 1

        按照题目要求,我们首先要找到93的第4位,也就是橙色标注的数字 1 0 1 1   1 0 1

       之后从这一位算起,往右数3位,,也就是橙色标注的数字  1 0 1 1   1 1 1

       我们要把上一行中橙色标注的这三位,替换为数字211二进制的最后三位

        红色标注的是211二进制的最后三位:1 1 0 1   0 0 1 1

       所以我们的最终目标就是把1 0 1 1    1 1 1 变成 1 0 0 1    1 1 1

    代码如下

    #include<stdio.h>
    
    unsigned setbits(unsigned x, int p, int n, unsigned y)
    {
    	return ((x & ~(~(~0 << n) << p+1-n)) | ((~(~0 << n) & y) << p+1-n));
    }
    int main()
    {
    	printf("%d
    ",setbits(93,4,3,211));
    	return 0;
    }
    

      

    运行结果

    欢迎大家关注公众号:农大CPU

       

  • 相关阅读:
    整数N分解,搭积木,离散数学中的母函数,ZOJ(1163)
    背包问题模板,POJ(1014)
    DP之背包问题详解及案例
    Java基础部分全套教程.
    一位资深程序员大牛给予Java初学者的学习路线建议
    给Java新手的一些建议——Java知识点归纳(Java基础部分)
    一位10年Java工作经验的架构师聊Java和工作经验
    假如时光倒流,我会这么学习Java
    一位资深程序员大牛给予Java初学者的学习路线建议
    2年Java开发工作经验面试总结
  • 原文地址:https://www.cnblogs.com/jerryleesir/p/12872830.html
Copyright © 2011-2022 走看看