草庐IT

位运算:按位与、按位或、按位异或、按位左移、按位右移

sunny-ll 2023-04-18 原文

目录

一、基础知识补充

    (1)位运算

    (2)二进制的详细操作

二、位运算

    (1)按位与(&)

    (2)按位或(|)

    (3)按位异或(^)

      (4)按位左移(<<)

    (5)按位右移(>>)

三、位运算例题

    题目描述:

    题解:

四、共勉


一、基础知识补充

    (1)位运算

    位运算符要比一般的算术运算符速度要快,而且可以实现一些算术运算不能实现的功能(文章后面会举例子)。如果在完成代码的时候需要做到开发效率高,位运算是必不可少的。位运算用来对二进制位进行操作,包括:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、按位左移(<<)、按位右移(>>) 。

    (2)二进制的详细操作

    在进行位运算的时候,会用到大量的二进制源码、反码、补码,所以有需要的朋友可以看看我的上一篇文章哦!!!

    文章的链接:  http://t.csdn.cn/dasNJ

二、位运算

    (1)按位与(&)

    1. 应用范围:必须在整数范围内进行

    2. 运算方法:将整数从十进制转化为二进制数,上下比较,有零则零 ,两个都是 1 才是 1。

    3. 运算编码:补码

    4. 输出方式:整形表达式计算使用在内存中的是补码,打印和看到的都是源码。

    举例:将 3 & (-5)

// int 为整型4个字节有32个bit位
int a = 3 ;  // 00000000 00000000 00000000 000000011   正数,源码=反码=补码
int b = -5 ; // 10000000 00000000 00000000 000000101   -5的源码
             // 11111111 11111111 11111111 111111010   -5的反码
             // 11111111 11111111 11111111 111111011   -5的补码

int c = a & b ;  //按位与:上下比较,有零则零,两个都为 1 才是 1

             // 00000000 00000000 00000000 00000011   3的补码
             // 11111111 11111111 11111111 11111011   -5的补码

     最终结果// 00000000 00000000 00000000 00000011   ----(3)整数,源码=反码=补码

    (2)按位或(|)

    1. 应用范围:必须在整数范围内进行

    2. 运算方法:上下比较有 1 则为 1,两个都是 0 才是 0

    3. 运算编码:补码

    4. 输出方式:整形表达式计算使用在内存中的是补码,打印和看到的都是源码。

    举例:3 |  (-5)

// int 为整型有4个字节,32个bit位
int a = 3 ;  // 00000000 00000000 00000000 00000011   正数,源码=反码=补码
int b = -5 ; // 10000000 00000000 00000000 00000101   -5的源码
             // 11111111 11111111 11111111 11111010   -5的反码
             // 11111111 11111111 11111111 11111011   -5的补码

int c = a | b ;    //按位或:上下比较,有 1 则 1,两个都是 0 才是 0

              // 11111111 11111111 11111111 11111011   -5的补码
              // 00000000 00000000 00000000 00000011   3的补码

      最终结果// 11111111 11111111 11111111 11111011  为负数,是补码
             // 11111111 11111111 11111111 11111010   是反码,补码-1
             // 10000000 00000000 00000000 00000101   是源码,各个位按位取反-----(-5)

    (3)按位异或(^)

    1. 应用范围:必须在整数范围内进行

    2. 运算方法:上下比较,相同为 0 ,相异为 1 

    3. 运算编码:补码

    4. 输出方式:整形表达式计算使用在内存中的是补码,打印和看到的都是源码。

    举例: 3  ^ (-5)

// int 为整型有4个字节32个bit位
int a = 3 ;  // 00000000 00000000 00000000 00000011  正数,源码=反码=补码
int b = -5 ; // 10000000 00000000 00000000 00000101  负数,(-5)的源码
             // 11111111 11111111 11111111 11111010  -5的反码
             // 11111111 11111111 11111111 11111011  -5的补码

int c = a ^ b ; //按位异或:上下比较,相同为0,相异为1


// 11111111 11111111 11111111 11111011  -5的补码
// 00000000 00000000 00000000 00000011  3的补码


//异或 :11111111 11111111 11111111 11111000  负数,补码
      // 11111111 11111111 11111111 11110111  反码
      // 10000000 00000000 00000000 00001000  源码-----(-8)

      (4)按位左移(<<)

    1. 应用范围:必须在整数范围内进行

    2. 运算方法:把二进制数向左移动一位,左边溢出的丢弃,右边补零

    3. 编码运算:补码

    4. 输出方式:整形表达式计算使用在内存中的是补码,打印和看到的都是源码。

    举例:将 a = 4 左移一位

// int 为整型,有4个字节,32个bit位
int a = 4 ;       // 00000000 00000000 00000000 00000100,正数,源码=反码=补码
int b = a << 1 ;  // 把a左移一位,左边丢弃,右边补零
                  // 00000000 00000000 00000000 00001000 ----(8)

    (5)按位右移(>>)

    1. 应用范围:必须在整数范围内进行

    2. 运算方法:把二进制数向右移动一位,右边丢弃,左边补原符号位

    3. 编码运算:补码

    4. 输出方式:整形表达式计算使用在内存中的是补码,打印和看到的都是源码。

int a = -4 ; // 10000000 00000000 00000000 00000100 负数,源码
             // 11111111 11111111 11111111 11111011  -4的反码
             // 11111111 11111111 11111111 11111100  -4的补码
int b = >> 1 ; // 把b向右移动一位,右边丢弃,左边补原符号位
               // 11111111 11111111 11111111 11111110  负数,补码
               // 11111111 11111111 11111111 11111101  反码
               // 10000000 00000000 00000000 00000010  源码----(-2)

    此时我们可以发现一个整数,左移有乘2的效果,右移有除二的效果。

三、位运算例题

    题目描述:

    不创建第三变量,进行变量 a , b 的数值交换

    题解:

    (方法一):简单数位运算,但是不能满足所有需求

#include <stdio.h>
int main()
{
	int a = 5;
	int b = 3;
	a = a + b;
	b = a - b;
	a = a - b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

    若 a , b 两个数相加的和刚好超过 int 的取值范围,方法一就不可行。

    (方法二):位运算,简单,高效

//找规律
//3^3=0
//5^5=0
//3^5^5=3
//3^5^3=5
//3^5=6
// 异或支持交换律

#include <stdio.h>
int main()
{
	int a = 8;
	int b = 9;
	int z;
	z = a ^ b;  //设置密码z
	b = z ^ b;  //b=a^b^b=a
	a = z ^ a; //a=a^b^a=b
	printf("a=%d b=%d\n", a, b);
	return 0;
}

四、共勉

    这篇文章就是我对位运算的理解,如果大家有什么问题可以在评论区说出来哦,我们共同进步,一起加油!!!

 

有关位运算:按位与、按位或、按位异或、按位左移、按位右移的更多相关文章

  1. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  2. ruby - 带括号和 splat 运算符的并行赋值 - 2

    我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow

  3. ruby - 定义自定义 Ruby 运算符 - 2

    问题是:除了在“OperatorExpressions”?例如:1%!2 最佳答案 是的,可以创建自定义运算符,但有一些注意事项。Ruby本身并不直接支持它,但是superatorsgem做了一个巧妙的把戏,将运算符链接在一起。这允许您创建自己的运算符,但有一些限制:$geminstallsuperators19然后:require'superators19'classArraysuperator"%~"do|operand|"#{self}percent-tilde#{operand}"endendputs[1]%~[2]#Out

  4. ruby - Ruby 中 <=> 运算符的名称是什么?他们怎么调用它? - 2

    在Ruby中有运算符(operator)。在API中,他们没有命名它的名字,只是:Theclassmustdefinetheoperator...Comparableusestoimplementtheconventionalcomparison......theobjectsinthecollectionmustalsoimplementameaningfuloperator...它叫什么名字? 最佳答案 参见上面的@Tony。然而,它也被称为(俚语)“宇宙飞船运算符(operator)”。

  5. ruby - 将运算符传递给函数? - 2

    也许这听起来很荒谬,但我想知道这对Ruby是否可行?基本上我有一个功能...defadda,bc=a+breturncend我希望能够将“+”或其他运算符(例如“-”)传递给函数,这样它就类似于...defsuma,b,operatorc=aoperatorbreturncend这可能吗? 最佳答案 两种可能性:以方法/算子名作为符号:defsuma,b,operatora.send(operator,b)endsum42,23,:+或者更通用的解决方案:采取一个block:defsuma,byielda,bendsum42,23,

  6. ruby - OR 运算符和 Ruby where 子句 - 2

    可能真的很简单,但我很难在网上找到关于这个的文档我在Ruby中有两个activerecord查询,我想通过OR运算符连接在一起@pro=Project.where(:manager_user_id=>current_user.id)@proa=Project.where(:account_manager=>current_user.id)我是ruby​​的新手,但我自己尝试使用||@pro=Project.where(:manager_user_id=>current_user.id||:account_manager=>current_user.id)这没有用,所以1.我想知道如何在

  7. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

  8. ruby - 我可以在 Ruby 中动态调用数学运算符吗? - 2

    ruby中有这样的东西吗?send(+,1,2)我想让这段代码看起来不那么冗余ifop=="+"returnarg1+arg2elsifop=="-"returnarg1-arg2elsifop=="*"returnarg1*arg2elsifop=="/"returnarg1/arg2 最佳答案 是的,只需像这样使用send(或者更好的是public_send):arg1.public_send(op,arg2)这是可行的,因为Ruby中的大多数运算符(包括+、-、*、/、andmore)只需调用方法。所以1+2与1.+(2)相同

  9. ruby - 如何在不使用文本的情况下找到 Ruby 运算符的含义? - 2

    您如何找到有关代码中运算符用法的信息(最好是通过Google)?在这种情况下,我想找到这段代码在Ruby中的含义。x=[1,2,3]x.send:[]=,0,2x[0]+x.[](1)+x.send(:[],2)我要你教我如何钓鱼——不要告诉我运算符(operator)是做什么的。当我去Google并尝试搜索符号时,我得到的示例或教程没有涵盖特定的用法。https://stackoverflow.com/questions/1165786/how-to-search-for-punctuation-that-gets-ignored-by-google表示谷歌驳回了这种表示法;我寻找“

  10. ruby - 猴子修补 float 中缀运算符产生意想不到的结果 - 2

    重新定义Float#/似乎没有效果:classFloatdef/(other)"magic!"endendputs10.0/2.0#=>5.0但是当另一个中缀运算符Float#*被重新定义时,Float#/突然采用了新的定义:classFloatdef/(other)"magic!"enddef*(other)"spooky"endendputs10.0/2.0#=>"magic!"我很想知道是否有人可以解释这种行为的来源,以及其他人是否得到相同的结果。ruby:ruby2.0.0p353(2013-11-22)[x64-mingw32]要快速确认错误,请运行thisscript.

随机推荐