计算机基础之位运算、以及位运算实现加减乘除

众所周知,由于电路的复杂性因素,电脑中都使用二进制数,只有0和1两个数码,逢二进一,最容易用电路来表达,比如0代表电路不通,1代表电路通畅。那么,什么是二进制呢?

比如说我们所熟悉的十进制,通俗的说是由0,1,2,3,4,5,6,7,8,9这十个数字组成,如果比9再大一个数,就会进一位,高位加一,低位重置,也就是10。

再比如八进制,是由0,1,2,3,4,5,6,7这八个数组成,逢八进一,比7大一个,就会进一位,也就是10。

以此类推,二进制,就是由0和1组成,逢二进一。

因为计算机只认识二进制,所以它也压根不知道什么是加减乘除,我们之所以能用在电脑上使用计算器进行加减乘除的操作,是因为底层进行了一些位运算的操作,来达到加减乘除的目的。

位运算可以理解为就是二进制之间的操作运算,有以下几种:

(注意,在本文中,所有二进制的长度都是以字节为单位。额…计算机的存储单位分为,位:一个二进制位、字节:一个字节等于八位、字:一个字等于十六位、双字:一个双字等于32位、四字:一个四字等于六十四位

1.按位与(&)

如果两个相应的二进制位都为1,则该位的结果值为1,否则为0。

比如  0 1 0 1 0 0 0 1和0 0 0 0 1 0 1 1进行与运算

0 1 0 1 0 0 0 1

0 0 0 0 1 0 1 1

-------------------

0 0 0 0 0 0 0 1

运算后结果就是 0 0 0 0 0 0 0 1;

2.按位或(|)

如果两个相应的二进制位中只要有一个为1,该位的结果值为1。

比如  0 1 0 1 0 0 0 1和0 0 0 0 1 0 1 1进行或运算

0 1 0 1 0 0 0 1

0 0 0 0 1 0 1 1

-------------------

0 1 0 1 1 0 1 1 

运算后结果就是 0 1 0 1 1 0 1 1;

3.按位异或(^)

若参加运算的两个二进制位值不同则为1,否则为0。

比如  0 1 0 1 0 0 0 1和0 0 0 0 1 0 1 1进行异或运算

0 1 0 1 0 0 0 1

0 0 0 0 1 0 1 1

-------------------

0 1 0 1 1 0 1 0

运算后结果就是 0 1 0 1 1 0 1 0;

4.取反(~)

~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0。

比如  0 1 0 1 0 0 0 1进行取反操作

0 1 0 1 0 0 0 1

运算后结果就是 1 0 1 0 1 1 1 0;

5.左移(<<)

整个二进制向左移动n位,高位去除;

6.右移(>>)

整个二进制向右移动n位,无符号位 高位补0,有符号位 高位 补符号位;

讲到这里可能要跟大家解释下什么是无符号和有符号:

因为计算机只能识别0和1,所以前人想出了一个办法,以最高位表示符号位(正或者负),其余位表示数值大小,这样的数就被称为有符号数,而无符号数则是所有位都用于表示数的大小。

现在,我们就来看看加减乘除在计算机内部是怎样实现的。

加法:

例如13 + 11,在计算机中13会被转成二进制 0 0 0 0 1 1 0 1 ,11则会被转成 0 0 0 0 1 0 1 1,

    0 0 0 0 1 1 0 1

    0 0 0 0 1 0 1 1

加--------------------

    0 0 0 1 1 0 0 0

这是我们通过加法计算得到的结果,0 0 0 1 1 0 0 0 ,也就是24,但是,计算机并不会加法,只会与、或、异或等位运算,所以,我们只能通过位运算去达到加减乘除的效果。

      0 0 0 0 1 1 0 1

      0 0 0 0 1 0 1 1

与  -------------------- 

      0 0 0 0 1 0 0 1

      0 0 0 0 1 1 0 1

      0 0 0 0 1 0 1 1

或  -------------------- 

      0 0 0 0 1 1 1 1

      0 0 0 0 1 1 0 1

      0 0 0 0 1 0 1 1

异或-------------------- 

      0 0 0 0 0 1 1 0

对比一下不难发现,异或的结果在不考虑进位的情况下,跟加法的结果是一样的,那么进位的数我们该怎么处理呢?

首先对异或的结果进行判断,判断是否存在进位,如果不存在 ,那么异或的结果就是加法的结果。

那么,怎么判断是否存在进位呢?我们观察一下不难发现,只有相同位都是1的情况下,才会存在进位,那么,对应到位运算中就是与,与运算只有相同位都是1,结果才为1。

      0 0 0 0 1 1 0 1

      0 0 0 0 1 0 1 1

与  -------------------- 

      0 0 0 0 1 0 0 1

与运算后的结果是0 0 0 0 1 0 0 1,说明两个二进制位相加是存在进位的,那么,我们需要对与运算后的结果进行左移一位,因为通过计算进位后,结果本身会进一位。

0 0 0 0 1 1 0 1左移一位后的结果是0 0 0 1 0 0 1 0。

接着我们将异或后的结果,与左移后的结果再进行异或运算。

      0 0 0 0 0 1 1 0

      0 0 0 1 0 0 1 0

异或-------------------- 

      0 0 0 1 0 1 0 0

异或运算后的出结果0 0 0 1 0 1 0 0,每次异或之后我们都需要判断是否存在进位。

      0 0 0 0 0 1 1 0

      0 0 0 1 0 0 1 0

与  -------------------- 

      0 0 0 0 0 0 1 0

发现存在进位后,再对进位的结果左移一位,得到  0 0 0 0 0 1 0 0。

然后再将异或结果与左移后的结果进行异或运算。

      0 0 0 1 0 1 0 0

      0 0 0 0 0 1 0 0

异或-------------------- 

      0 0 0 1 0 0 0 0

再与运算判断是否存在进位。

      0 0 0 1 0 1 0 0

      0 0 0 0 0 1 0 0

与  -------------------- 

      0 0 0 0 0 1 0 0

存在,则进行左移操作,得到0 0 0 0 1 0 0 0。

然后,再重复上述步骤。

      0 0 0 1 0 0 0 0

      0 0 0 0 1 0 0 0

异或-------------------- 

      0 0 0 1 1 0 0 0

      0 0 0 1 0 0 0 0

      0 0 0 0 1 0 0 0

与  -------------------- 

      0 0 0 0 0 0 0 0

OK,到这终于不用进位了,上一步异或操作,就是最终的结果0 0 0 1 1 0 0 0,跟上面通过加法得到的结果是一致的。

最后总结下位运算进行加法操作的步骤:

1.对两个二进制位进行异或运算

2.对两个二进制位进行与运算,如果结果为0,则不存在进位,上一次异或运算结果就是加法的最终结果,如果存在进位,则将与运算后的结果进行左移一位。

3.对上次异或运算结果和左移结果重复步骤1、步骤2的操作。

减法:

其实减法的操作,就是加法的操作

例如9 - 5,可以看做9 + (-5),9的二进制是 0 0 0 0 1 0 0 1,-5的二进制是 1 1 1 1 1 0 1 1 ,至于-5的二进制为什么会是这个,可以参考我的另一篇博客https://blog.csdn.net/qq_32069155/article/details/92851142

      0 0 0 0 1 0 0 1

      1 1 1 1 1 0 1 1

异或-------------------- 

      1 1 1 1 0 0 1 0

      0 0 0 0 1 0 0 1

      1 1 1 1 1 0 1 1

与  -------------------- 

      0 0 0 0 1 0 0 1

发现存在进位,则将与运算结果左移一位,得到 0 0 0 1 0 0 1 0,然后将上次异或结果和左移结果再进行异或运算

      1 1 1 1 0 0 1 0

      0 0 0 1 0 0 1 0

异或-------------------- 

      1 1 1 0 0 0 0 0

      1 1 1 1 0 0 1 0

      0 0 0 1 0 0 1 0

与  -------------------- 

      0 0 0 1 0 0 1 0

发现存在进位,则将与运算结果左移一位,得到 0 0 1 0 0 1 0 0,然后将上次异或结果和左移结果再进行异或运算

      1 1 1 0 0 0 0 0

      0 0 1 0 0 1 0 0

异或-------------------- 

      1 1 0 0 0 1 0 0

      1 1 1 0 0 0 0 0

      0 0 1 0 0 1 0 0

与  -------------------- 

      0 0 1 0 0 0 0 0

发现存在进位,则将与运算结果左移一位,得到 0 1 0 0 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算

      1 1 0 0 0 1 0 0

      0 1 0 0 0 0 0 0

异或-------------------- 

      1 0 0 0 0 1 0 0

      1 1 0 0 0 1 0 0

      0 1 0 0 0 0 0 0

与  -------------------- 

      0 1 0 0 0 0 0 0

发现存在进位,则将与运算结果左移一位,得到 1 0 0 0 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算

      1 0 0 0 0 1 0 0

      1 0 0 0 0 0 0 0

异或-------------------- 

      0 0 0 0 0 1 0 0

      1 0 0 0 0 1 0 0

      1 0 0 0 0 0 0 0

与  -------------------- 

      1 0 0 0 0 0 0 0

发现存在进位,则将与运算结果左移一位,得到 0 0 0 0 0 0 0 0,然后将上次异或结果和左移结果再进行异或运算

      0 0 0 0 0 1 0 0

      0 0 0 0 0 0 0 0

异或-------------------- 

      0 0 0 0 0 1 0 0

      0 0 0 0 0 1 0 0

      0 0 0 0 0 0 0 0

与  -------------------- 

      0 0 0 0 0 0 0 0

发现不存在进位,则上次异或结果 0 0 0 0 0 1 0 0就是最终结果,也就是 4。

乘法:

乘法其实跟加法是一样的,只不过是多加了几次而已,这里就偷个懒不多描述了。

除法:

除法其实就是减法,只不过是计算能减多少次而已,这里也偷个懒就不多描述了。

---------------------------------------------------------------------------------------------------------------------------------------

PS:到这你可能还会好奇,为什么异或会跟加法结果一致,我在这里再补充下。

我们要知道,异或运算,是相同位的值不同才为1,值相同则为0。

而且,两个相同位之间出现的可能性,只有4种:

      0 0 0 0 0 0 0 0

      0 0 0 0 0 0 0 0

异或-------------------- 

      0 0 0 0 0 0 0 0

相同位是0 和 0,异或的结果是0,跟直接用加法运算0 + 0的结果也是一致的;

      0 0 0 0 0 0 0 0

      0 0 0 0 0 0 0 1

异或-------------------- 

      0 0 0 0 0 0 0 1

相同位是0 和 1,异或的结果是1,跟直接用加法运算0 + 1的结果也是一致的;

      0 0 0 0 0 0 0 1

      0 0 0 0 0 0 0 0

异或-------------------- 

      0 0 0 0 0 0 0 1

相同位是1 和 0,异或的结果是1,跟直接用加法运算1 + 0的结果也是一致的;

      0 0 0 0 0 0 0 1

      0 0 0 0 0 0 0 1

异或-------------------- 

      0 0 0 0 0 0 0 0

相同位是1 和 1,异或的结果是0,这里跟加法运算1 + 1的结果就不一样了,因为发生了进位。

这四种结果中,有三种结果跟直接加法运算的结果是一样的,最后一种因为存在进位,所以不考虑,上面说过,不参考进位的情况下,异或运算和直接加法运算的结果是一致的。所以,可以肯定的说,不参考进位的情况下,异或运算和直接加法运算的结果一致。

相信到这里,大家应该对异或为什么跟加法结果是一致,有了一定的认识。

本文到此就告一段落了,上述内容,都是我参照https://ke.qq.com/course/320677?taid=2384548663190693这里的视频教程,再进行总结的,如果有什么不对的地方,还请指正!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值