day07.计算机不会做加法



第7节:计算机不会做加法
之前课程里面讲到计算机如何存取数字,那么我们讲解了计算机如何存储正数(有符号的正数)和无符号的正数,在后面的课程中我会告诉大家计算机如何存储浮点数与如何存储字母如何存储汉字,那么仅仅知道计算机如何存储数字还是不够的,这节课主要来了解计算机是如何运算的,大家知道计算机只能认识0和1,这就意味所有的运算归根结底也就是直接对0和1做运算(通常称为位运算)。

举个例子说:
                      比如:2+3=?和2-3=?计算机是不认识2和3,和它的“+”、“-”符号的,那么计算机都是通过什么方式计算的呢?由很多人不理解,我们只知道计算机2+3=5能算出来。我为什么要了解那么多的细节?我们为什么还要去学位运算呢?这种想法是错误的,让我告诉你为什么?
                     
 1)有些功能在我们做开发的时候是必须通过位运算才能实现的。比如:写调试器(自己写过调试器的人那你通过位运算去判断CPU各种状态,如标志位的状态位,一个32位的表里面,不同的位置它的状态是不一样的。)如果你不会位运算那你怎么能得到某一个位的值,你怎么来修改某个位的值,当然从来不做类似这么一个相对难点的项目的话,那就不用说了。在说这种调试器的项目也不是什么高大上的项目。
 2)情况大公司面试题:比如2*8效果最高的实现方式是什么。

1、与运算and(&)例子:

              1101 0001
and(&)    1101 1000
----------------------
              1001 0000

有些没有用过汇编和C语言这些都不主要,理解原理才是重要,写代码就是体力活,在汇编里边用的是“and” 与运算,在C语言里面用的是“&” 与与运算,这些都不重要。首先了解如何做与运算,上面的例子,与运算的结果是什么?结果是:都是1的才是1,最后的值是1001 0000。

2、或运算or(|)例子:

                1011 0001
or(|)          1101 1000
----------------------
                1111 1001

或运算最后的结果是:1111 1001,这个值是怎么来的,原因是只要有做运算的时候,有1个1的情况结果就是1。

3、异或运算xor(^)例子:

              1011 0001
xor(^)     1101 1000
----------------------
              0110 1001

异或运算最后的结果是:0110 1001,这个值是怎么来的,原因是只要有做运算的时候,不同的情况结果就是1相同的情况为0。

4、非运算not(~) 例子:

not(~) 1101 1000
----------------------
           0010 0111
非运算最后的结果是:0010 0111,这个值是怎么来的,原因是对1101 1000做相反的操作,将1变成0,将0变成1。(需要注意的是,它是单目的,什么是单目?单目就是一个数字,它就是只要一个数字计算)。

5、移位运算
              左移:
                        各二进制位全部左移动若干位,高位丢弃,低位补0。
比如:
        shl(<<)       1101 1000       将这个数左移动2位
大家不要纠结在汇编如何写在C语言如何写,先理解,在汇编中左移动的时候使用shl,在C语言中左移动时候使用“<<”符号。1101 1000 这个数左移动两位就是将最高位的两个1丢弃,在后边添加2个0,得的结果是:0110 0000 ,这个就是左移。(左移比较好理想没有那么复杂)

              右移:
                        右移是什么呢?各二进制全部右移若干位,低位丢弃,高位补0或补符号位(就是补1)
比如:
        shr             1101 0101       结果是 0011 0101
        对应C语言(>>)
        unsigned    int  a = 10;
        printf("%d\n",a>>2);
       
        sar             1101 0101       结果是 1111 0101
        对应C语言(>>)
        int  a = 10;
        printf("%d\n",a>>2);
       
注意:以上这节课所讲的内容都是位来计算的。
我们来看使用sar表来向右移两位的话,最后0和1丢弃,最前面补两个1(这个是在汇编里面理想的意思)。如果想在前面补0用shr,想在前面补1用sar,然后在shr和sar中的各自的两位都丢弃。
但在C语言里不一样无论你是想补0还是补1,它使用的符号都是相同的“>>”,编译器怎么知道前面补0还是补1呢?

看代码中的unsigned int a = 10,告诉编译器它有一个值是10,宽度是int 32位的(双字),而unsigned告诉编译器是无符号数。
printf("%d\n",a>>2) ,a>>2 是右移2位,将前面的a = 10 向右移2位。
注意:(a = 10 是十进制的转换成是0000 0000 0000 1010将这个值向右移2位)

而sar例子中的值也是向右移2位,但是它的最高的符号位为0就补0,如果最高的符号位为1就补1。

总结:
这节课主题是计算机的加法,我就强调一点计算机做的所有的运算归根结底,全部变成位运算,总之计算机只会做位运算。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随行之旅

python国产化自动化

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值