美文网首页
02_二进制数据(计算机科学)

02_二进制数据(计算机科学)

作者: yishurensheng | 来源:发表于2017-11-18 12:17 被阅读0次

    带着问题学习(二进制数据)

    • 32位是几个字节?
    • 01011100对应的十进制是多少?
    • 00001111左移两位结果是多少?有什么规律?
    • 以补码形式表示的8位二进制数11111111,十进制为多少?
    • 二进制和十进制有什么区别?

    为什么要使用二进制?

    IC.png

            上图展示了一个较为简单集成电路的实例,而电脑就是由大量的集成电路芯片组成的,较为熟悉的CPU就是一个十分复杂的集成芯片。
            上图中的每一个管脚只有两种状态,分别是通电和不通电,那么这两种状态就可以对应二进制中的0和1,这就是为什么电脑中需要二进制进行运算。

    二进制值能表达的含义

    image.png

           二进制能够表示这么多种类的数据格式,归根结底就是在计算机中所有的数据都是以数值的形式存储的,它们唯一的区别是在解析的时候不同,不同的数据格式有着不同的解析方式。

    二进制和十进制的转换

    • 二进制是一种计数方式
    • 二进制值不仅仅是一个数


      image.png

             上图展示了一个简单的浮点数和二进制数之间的转换。

    二进制的运算

    二进制表示负数

            在计算机中,是如何使用二进制表示负数呢?这就需要做一些硬性规定了,为了简单起见,我们拿一个char类型的数据类型举一个简单的例子。众所周知,一个char类型在计算机内存中占据8个bit,并且它的最高bit是用来表示正负号的,我们想知道-3的二进制char类型是什么样子,该怎么办呢?其实很简单,-3的二进制就是+3的二进制取反加1,过程如下:
    3的二进制为:00000011
    00000011取反为:11111100
    11111100加1为:11111101
    所以11111101就是-3的二进制表示。
    我们可以再举一个例子,比如我们想知道-128的二进制表示,那么根据上面的过程:
    128的二进制为:10000000
    10000000取反为:01111111
    01111111加1为:10000000
    所以10000000就是-128的二进制表示。
    相信通过上面的两个例子,您会对二进制表示负数有一个较为深刻的了解,如果您还不是太了解,我们再举一个简单的减法运算,比如10-7=?,我们知道,在计算机中,是没有减法运算的,它只有加法运算,所以我们不得不把上式改写为:10+(-7)=?,这样才能被计算机直接计算。现在的问题就是如何找到-7的二进制表示,和上面的方法一样:
    7的二进制表示为:00000111
    00000111取反为:11111000
    11111000加1为:11111001
    所以-7的二进制为:11111001
    而10的二进制为:00001010
    所以10+(-7)=00001010+11111001得出100000011共9bit,但是我们的数据类型是char,它只有8bit,所以不得不把最高位1舍弃,得到10+(-7)=00000011的值为3,和我们用十进制算的结果一模一样。
    相信大家通过这几个例子,会对二进制表示负数以及计算机中对减法是如何操作了吧!!!

    按位运算符

            C语言提供了6个位操作运算符。这些运算符只能作用于整型操作数,即只能作用于带符号或者无符号的char、short、int、long类型:

    1. & 按位与(AND);
    2. | 按位或(OR);
    3. ^按位异或(XOR);
    4. << 左移;
    5. 右移;

    6. ~按位求反(一元运算符)。
    二进制的按位与运算符(&)

            只有两个位都是1的时候,这时的结果才是1,其它所有情况的结果都是0,比如:
    1 & 1 的结果是:1;
    1 & 0 的结果是:0;
    0 & 1 的结果是:0;
    0 & 0 的结果是:0。

    二进制的按位或运算符(|)

            只有两个位都是0的时候,这时的结果才是0,其它所有情况的结果都是1,比如:
    1 | 1 的结果是:1;
    1 | 0 的结果是:1;
    0 | 1 的结果是:1;
    0 | 0 的结果是:0。

    二进制的按位异或运算符(^)

            只有两个位不相等的时候,这时的结果才是1,其它所有情况的结果都是0,比如:
    1 ^ 1 的结果是:0;
    1 ^ 0 的结果是:1;
    0 ^ 1 的结果是:1;
    0 ^ 0 的结果是:0。

    二进制左移

            假如有一个char类型的变量,它的值为3,那么它的二进制表示为:00000011,分别左移1位、2位和3位,我们看得到的数值是多少!
    00000011左移1位,得到00000110,它的值为6;
    00000011左移2位,得到00001100,它的值为12;
    00000011左移3位,得到00011000,它的值位24,;
    从上面不难得到这样的一个规律,就是在不溢出的情况下,左移几位,就表示原来的数乘以2的多少次幂。

    二进制右移

            逻辑右移:我们把左边全部补0,不考虑符号位的右移称为逻辑右移。
            二进制的右移就不像二进制左移那样简单了。我们先看一个例子,还是以一个char类型的变量为例,它的值为-128,让它右移2位,如果按照左移的规律,那么-128右移2位的值应该是-128除以2的2次幂,即-32。那么我们下面来右移一下看看。我们再推倒一次-128的二进制表示:
    128的二进制表示为:10000000(这里我们先不考虑最高位表示正负号,只是考虑数值的大小);
    10000000取反后为:01111111;
    01111111加1为:10000000;
    所以-128的二进制表示为10000000。
    假如我们还是按照左移的方式右移,那么10000000右移2位位00100000,很显然这不是一个负数,因为负数的最高位是1,这不是我们想要的结果,我们称这样的右移为逻辑右移。
            算术右移:左边补的数和符号有关的右移称为算术右移。
            我们还是拿char类型的变量,值为-128来举例子。从上面知道-128的二进制表示为:10000000。那么它算术右移2位是11100000,11100000是-32吗?一般人不好看出来,不过没关系,我们推倒一下-32的二进制不就行了嘛!!!
    32的二进制表示为:00100000;
    00100000取反后为:11011111;
    11011111加1为:11100000。
    所以-128算术右移后的二进制11100000值就是-32。
    无论是逻辑右移还是算术右移,它们都有存在的意义。在单片机编程中,比如跑马灯程序的编写,就有可能需要逻辑右移,但是这些又不是数值,更不是负数,它只是一些简单的数据。

    二进制的按位求反运算符(~)

            取反就是将0变成1.将1变成0,比如:
    ~1 的结果是:0;
    ~0 的结果是:1。

    二进制数表示浮点数

    关于浮点数的计算,这里有一个比较好的参考。
    二进制表示浮点数
    我们大概了解计算机中的浮点数是IEEE制定的一套表示方法,它的表示形式是科学计数法,如果想深入了解浮点数的表示请参考上面的链接,也可以自行查其它的资料,这里我们就不做深入讲解了。
    由于计算机表示的浮点数大多数都是不精确的,只有部分小数是精确的(比如0.5、0.25、0.125等等),所以对于我们程序来说,重点要做的是:

    1. 不使用浮点数直接进行运算,而是使用整数进行运算,得到结果后,再除以相应的倍数,这样得到的结果才比较可靠;
    2. 在误差允许的情况下可以直接使用浮点数进行运算。

    相关文章

      网友评论

          本文标题:02_二进制数据(计算机科学)

          本文链接:https://www.haomeiwen.com/subject/isjevxtx.html