zoukankan      html  css  js  c++  java
  • 【算法】详解进制

    目录结构:

    contents structure [+]

    1,为什么计算机代码需要用2进制表示

      大家都知道我们熟练的机制是十进制,也就是(0到9),逢10进1。如果要让电脑使用十进制,首先,应该让电脑能够识别出10个数字。通常的考虑是,通过元器件中电压的高低水平来分别标识10个数字。假如最高电压为10V,那么每个数字标识的就是1V,这种情况造成的后果就是每个数字的电压很容易收到外界电压干扰。除了这种问题,还有一个更大的问题,就是如果要在硬件上识别这10中状态,其电路结构将非常复杂。

       由于二进制数只有2个数码,电路就很简单了,因为只有两种稳定状态下的元件。二进制主要有以下优点:

      *运算规则简单

      *适合逻辑运算

      *易进行转化

      *抗干扰能力强

    2,原码、反码、补码的关系

      首先需要知道,电脑的编码都是补码,正数的原码、反码和补码都是一样的,负数的补码的是原码按位取反得到反码后再加1。

      比如:

        1的原码为:00000001

        1的反码为:00000001

        1的补码为:00000001

        -1的原码为:10000001

        -1的反码为:11111110

        -1的补码为:11111111

      2.1为什么需要反码、补码

        计算机中没有减法、乘法、除法运行,都是通过加法来实现的。比如通过1+(-1)来实现减法。

        不使用反码和补码:

          3-2=3+(-2)=0000 0011+1000 0010=1000 0101=-5

          显然结果不正确。

        使用反码不使用补码:

          3-2=3+(-2)=0000 0011+1111 1101=1 0000 0000=0

          这里得到结果的二进制有9位,如果我们只是考虑8位,那么结果取后面8个0,转化位十进制也就是0。

        使用补码

          3-2=3+(-2)=0000 0011+1111 1110=0 0000 0001=1

          使用补码就能得到正确的答案

    2.2原码、反码、补码之间的关系

    计算机中最终计算的都是机器码,对于数字来说也就是下面的补码。正数的原码、反码、补码相同,负数的反码是原码按位取反(符号位不变),负数的补码是反码加1(符号位不变)。原码的计算规则是,首先得到这个数的绝对值的二进制,然后再判断这个数是正数还是负数,如果这个数是正数把最高位赋值为0,如果是负数就把最高位赋值为1。

    比如:-1

    原码:1000 0001(-1绝对值的二进制为0000 0001,然后由于-1是负数,所以把最高位赋值为1.)

    反码:1111 1110

    补码:1111 1111

    所以计算机中存储-1的最终代码为1111 1111

    比如:-128

    原码:1000 0000(首先-128的二进制是1000 0000,然后-128是一个负数所以把最高位赋值为1,恰好最高位已经是1,所以-128原码就是1000 0000)

    反码:1111 1111

    补码:1000 0000

    所以在计算机中存储-128的最终代码为1000 0000

    还有需要注意的就是,如果我们在赋值的时候直接给变量赋二进制,那么这里是赋值的就是补码,也就是机器码。

    3,进制的转化

      3.1 十进制和二进制的相互转化

      十进制转二进制规则:整数部分除2取余,倒序排列。小数部分乘2取整,正序排列。

      例如

        某个数字:15.4

        整数部分为:0000 1111。

        小数部分为:

          0.4*2=0.8 取整为0 余下 0.8

          0.8*2=1.6 取整为1 余下 0.6

          0.6*2=1.2 取整为1 余下 0.2

          ...........

        保留两位小数,则是01

        于是15.4的二进制为0000 1111.01,可通过在线二进制转化器进行验证

      二进制转十进制的规则:按权展开,以此相加。

      例如

        某个二进制:0000 1111

        转化为十进制:1*2^(0)+1*2^(1)+1*2^(2)+1*2^(3)+0*2^(4)+0*2^(5)+0*2^(6)+0*2^(7)=15

      3.2 八进制和二进制的相互转化

        八进制转二进制规则:“一位转三位”;

        二进制转八进制规则:“三位合一位”;

      3.3 十六进制和二进制的相互转化

        十六进制转二进制规则:“一位转四位”;

        二进制转十六进制规则:“四位合一位”;

    4,一个字节能够表示的数据范围

      一个字节有8位,最高位为0表示正数,最高为1表示负数。

      那么:

        一个字节的正数范围“0000 0000 ”-“0111 1111”,转化为十进制就是“0”-“127”。

        一个字节的负数范围“1000 0000”-“1111 1111”,转化为十进制就是“-128”-“-1”。

      所以能够表示的数据范围“-128”-“127”。

    5,整型数据溢出

    接下来在java中运行如下代码:

    public class TestYc{
      public static void main(String [] args){
        byte b=(byte)130;
        System.out.println(b);//-126
      }
    }

    会输出如下-126,byte存储数据的范围(-128 到 127),显然130超过了127,所以存在数据溢出。

    我来计算一下,

    byte存储的最大整数为:127,对应的二进制代码为:0111 1111。

    当把128赋值给byte的时候,也就是127+1,对应的二进制代码为:0111 1111 + 0000 0001 = 1000 0000,对应的十进制为:-128。

    当把129赋值给byte的时候,也就是128+1,对应的二进制代码为:1000 0000 + 0000 0001=1000 0001,对应的十进制为:-127。

    当把130赋值给byte的时候,也就是129+1,对应的二进制代码为:1000 0001 + 0000 0001=1000 0010,对应的十进制为:-126。

    所以从计算我们看出,数据溢出几就在最大数的二进制加上几。

  • 相关阅读:
    [原]zoj3772--【水题】线段树区间查询+矩阵乘法
    站立会议报告(5)
    团队博客(8)
    站立会议报告(4)
    团队博客(7)
    站立会议报告(3)
    团队博客(6)
    站立会议报告(2)
    团队博客(5)
    团队博客(4)
  • 原文地址:https://www.cnblogs.com/HDK2016/p/6725659.html
Copyright © 2011-2022 走看看