zoukankan      html  css  js  c++  java
  • 计算机中的二进制运算

    一、计算机中的二进制位运算

      二进制的位运算并不是很难掌握,因为位运算总共只有5种运算:与、或、异或、左移、右移。与、或和异或运算的规律我们可以用表1总结如下。

    表1 与、或、异或的运算规律
    与(&) 0 & 0 = 0 1 & 0 = 0 0 & 1 = 0 1 & 1 = 1
    或(|) 0 | 0 = 0 1 | 0 = 1 0 | 1 = 1 1 | 1 = 1
    异或(^) 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0

      左移运算符m<<n表示把m左移n位。在左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。比如:

    • 00001010 << 2 = 00101000
    • 10001010 << 3 = 01010000

      右移运算符m>>n表示把m右移n位。在右移n位的时候,最右边的n位将被丢弃。但右移时处理最左边的情形要稍微复杂些。如果数字是一个无符号数值,则用0填补最左边的n位;如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说,如果数字是正数,则右移之后在最左边补n个0;如果数字是负数,则右移之后在最左边补n个1。下面是对8位有符号数进行右移的例子:

    • 00001010 >> 2 = 00000010
    • 10001010 >> 3 = 11110001

    二、unsigned与signed的区别

      首先回顾一下二进制的正负数表达方式。在计算机中使用补码表示正负数,其中正数的补码等于其本身,负数的补码则为原码取反再加1。用4位二进制表示-1 ~ 7如表2所示。

    表2 4位二进制
    补码 十进制数值
    0000 0
    0001 1
    0010 2
    0011 3
    0100 4
    0101 5
    0110 6
    0111 7
    1000 -8
    1001 -7
    1010 -6
    1011 -5
    1100 -4
    1101 -3
    1110 -2
    1111 -1

      由表2可知,在32位的系统中,int型的-1在计算机中的存储的补码为0xFFFF FFFF

      如同int a;一样,int 也能被其它的修饰符修饰。除void类型外,基本数据类型之前都可以加各种类型修饰符,类型修饰符有如下四种:

    1. signed----有符号,可修饰char、int(Int是默认有符号的)
    2. unsigned-----无符号,修饰int 、char
    3. long------长型,修饰int 、double
    4. short------短型,修饰int

    2.1 无符号整型(unsigned int)

    (1)我们都知道整型是4个字节(有些编译器不同,可能会是2个),即32位,无符号整型当然也为32位。
    (2)既然是32位,无符号整型的取值是32个0~32个1,即:0~4294967295
    (3) 我们举个例子:32位有点长,所以我们拿16位的unsigned short int 来举例。

      short int 是16位的,无符号的范围是0~65535。就拿十进制的32767来说,它的二进制为:0111 1111 1111 1111

      对于无符号的整型32767来说,它的二进制的最高位称为数据位,即那个0就是数据位,数据位是要参与运算的,如果我们把0改成1,即16个1,它的十进制就是65535(就是2的15次方+2的14次方...一直加到2的0次方),这是不同于有符号整型的。

    (4) 为了进行理解(3)中的含义,做一个程序说明:

    #include <stdio.h>
    main()
    {
        unsigned short int a=32767, b=a+1;//定义短整型无符号
        printf("a=%u
    b=%u
    ",a,b);//以无符号输出
    }
    

      定义的时候a=32767,也就是0111 1111 1111 1111,输出的依然是32767,a+1=32768, 二进制为1000 0000 0000 0000,输入依然为32768。根据(3)中讲解的,无符号整型的二进制最高位为数据位,数据位为0为1都是按照正常来算的。

    2.1 有符号整型(signed int)

    (1)有符号整型也是32位;

    (2)它的取值范围就与无符号整型不同了。它的范围是-2147483648~2147483647这个范围可以理解为无符号整型的一半变成了负数;

    (3) 我们举个例子:32位有点长,所以我们拿16位的unsigned short int 来举例。

      short int 是16位的,有符号的范围是-32768~32767。这个时候可能就有人发问了,32768用二进制表示为1000 0000 0000 0000,那么这个负的32768的负号又怎么理解呢?看下面。

      还是以32767为例子,它的二进制为:0111 1111 1111 1111。对于有符号整型32767来说,它的二进制最高位称为符号位(而不是数据位了),符号位顾名思义就是决定正负号的,规则:0是正,1为负。

    (4) 为了进行理解(3)中的含义,做一个程序说明:

    #include <stdio.h>
    main()
    {
    	// 定义有符号类型
        short int a=32767, b, c, d;
        b=a+1;
        c=a+2;
        d=a+3;
        printf("a=%d
    b=%d
    c=%d
    d=%d
    ",a,b,c,d);
    }
    

    (5)了解了什么是补码后再来看上述程序:32767的二进制为:0111 1111 1111 1111。我们来计算一下c的值为什么会等于-32767。c=32767+2,c的二进制为:1000 0000 0000 0001(32767的二进制加2),c的这个二进制是在计算机中存储的补码,需要将它转换为原码,也就是将c的二进制数减一再取反。得到的二进制原码为:1111 1111 1111 1111。我们已经说过,符号位为1,表示负值,并不参加运算,所以此二进制的十进制为:-32767

    (6)通过程序也可以发现一个规律,short int的取值范围是-32768~32767,把头尾连接起来形成一个环就可以了。

  • 相关阅读:
    孙陶然的五行文化,学习,真实用
    查看CPU使用率
    卸载windows补丁
    结束普通方法无法结束的进程
    三观
    如何知道一个EXE使用什么开发语言开发的
    文本文件处理,删除其中含有某些字符文本的行,一行命令搞定
    Delphi 字符串转日期,强大到窒息,VarToDateTime 解决了 困扰很久的小问题
    netstat -an查看到大量的TIME_WAIT状态的解决办法
    跨平台开发应用
  • 原文地址:https://www.cnblogs.com/flyingrun/p/13336828.html
Copyright © 2011-2022 走看看