• 进制


    进制

     程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。

    首先呢,了解位运算之前,我们要先指定进制之间的转换

    众所周知我们生活中所用的使用的数字是十进制数,而计算机所认识的是二进制

    所以呢,作为一个程序员我们必须要掌握二进制与十进制之间的互转与运算

    进制的相关关键字:

    1)高位

    一串二进制串,左面为高位

    2)低位

    一串二进制串,右面为低位

    3)原码

    我们所认识的二进制码,也就是我们进制间转换所得到的值,我们认识,但计算机不认识

    4)反码

    正数不需要做反码操作,,,负数的反码:符号位不变,0110  -------反码是原码转为补码的中间过程

    5)补码

    计算机所认识并可计算的字节码,正数的补码还是其原码本身,,负数的补码是其反码+1

    原码   ===》我们看到的    

    反码   ===》取反码

    补码   ===》真正运行的

    01.正数的原码,反码,补码都一致

    02.java中所有的数字都是有符号的  符号位 正数0  负数1

    03.负数的反码=符号位不变+其他位取反(10 01

    04.负数的补码=反码+1

    十进制转二进制

    可以明确的说,只要你会加法你就可以秒转

    先来一张比较牛逼的表:

    1024 512 256 128 64 32 16 8 4 2 1

    看不懂?没关系,接下来我们来说

    我们随便拿来一个数:765 (为了说明我这个办法确实nb,我们拿了一个比较大一点的数)

    我们已经有表了,那么,就套表呗

    首先找到765最近的一个比他小的数

    在他下面写个1,也就是512

    然后依次往后相加,发现相加比765大那么下面写0,然后舍去,只然后加下一个(注意是下面写过1的连续相加)最后可以得出来:

    1024 512 256 128 64 32 16 8 4 2 1

    1 0 1 1 1 1 1 0 1

    765的二进制数就是0 1011111101   (最前的0当符号位)

    因为是正数所以这既是它的原码也是它的补码

    那如果是负数呢?-765

    简单,就是拿到其正数的二进制数,改变符号位拿到原码:

    1 1011111101 这个值是我们转换的二进制码

    然后取反码(0110,)

    也就是 1(符号位不变)   0100000010   然后补码+1

    1 0100000011

    -765的补码就是1 0100000011  这个值是计算机可以进行计算解析的二进制码

     

    二进制转十进制

    可以明确的说在这里你只要会乘法运算,和明白数组下标就会秒转   或者拿出上面的万能转换表

    还是老规矩,随便写一个01组成的字符串,然后正负两种情况

    符号位为正:

    随便一个0符号位的二进制串 (既是原码也是补码)

    0 1101 ok,发大招,转换

    先忽略符号位,将后面的二进制串我们看成一个倒着的int类型数组,低位为0,依次往做+1

    古老算法:

    当前数*2的下标次方,然后将所有的数相加

    那么这个数就是:

    1*20次方+1*22次方+1*23次方=1+4+8= 13

    然后加上符号位  

    那么最终值就是+13

    万能表算法:

    1024 512 256 128 64 32 16 8 4 2 1

                                                1 1 0 1 

    那么。。。就是  8 +4 +1=13

    完美!!!

    符号位为负:

    如果拿到的是一个原码,,那就跟上面算法一样,只不过符号位为负的而已

    如果拿到一个补码,也就是中间多两部操作

    上面说了,原码转补码是  原码取反+1

    那么,反推,补码转原码就是。。。补码-1取反

    得到原码,再用上面其中一种算法就ok

     

    例子:1-2

    先把3转换成二进制

    00000011 (省略前24位数字 0 保留后八位)

    3的二进制是  00000011

    -8转换成二进制

    (注意:因为是负数 所以最高位的数字为1  则不管是反码,源码还是补码  最高位都不变都为1

    00001000  (因为是负数 所以最高位变为1

    10001000   -8的源码

    11110111   -8的反码(最高位不变 其他10  01

    11111000   -8的补码(在反码的基础上+1

    正数的原码,反码,补码都一致   所以3的补码就是他的二进制

    所以 补码-补码

        00000011

    +   11111000

    ================                           

            11111011   ----结果的补码

            11111010   ----结果的反码  (就是在补码的基础上-1

            10000101   ----结果的源码    -5

    -5(解析: 因为000001015的二进制 因为它的最高位是1  所以他为负数)

    (结果的二进制就是00000101

    例子: 1-3    

    先把4转换成2进制

     0 0 0 0 0 1 0 0

     -3转换成2进制

     1 0 0 0 0 0 1 1   -3的源码

      1 1 1 1 1 1 0 0   -3的反码(最高位不变 其他10  01

    1 1 1 1 1 1 0 1   -3的补码(在反码的基础上+1

       0 0 0 0 0 1 0 0

    +  1 1 1 1 1 1 0 1 1+1 1  自己变为0

    ===============

       0 0 0 0 0 0 0 1  ==== 结果的补码(000000011的二进制  因为 最高位是0

    可以看看这个表来总结:

    例子:

    20:(在18的前面32的后面 )

       16  16加多少等于 20 即使4 所以在4下面写上1其余补0

    1024 512 256 128 64 32 16 8 4 2 1

                                    1  0   1   0   0

    所以20的二进制就是10010100

    位运算

    算术右移 >>

    符号位不变,低位溢出删除,高位补零!

    先算出102进制

    0 0 0 0 1 0 1 0

      0 0 0 0 1 0 1 0    符号位不变,低位溢出删除,高位补零!

    ==========================================

    0 0 0 0 0 1 0 1     5

    1*20次方=1 

    0*21次方=0

    1*22次方=4    所以 他的结果是5

    举个例子:5>>2 (解析:把五的二进制数右移两位)

    先算出5 的二进制:

    0 101   右移两位,符号位不变

    0 00101 低位溢出删除,高位补零!

    最后结果:0 001

    转回十进制就是1

    如果是负数就是先转码然后位移

    算术左移 <<

    符号位不变,高位溢出删除,低位补零!

    举个例子:5<<2 (解析:把五的二进制数右移两位)

    先算出5 的二进制:

    0   101   左移两位,符号位不变

    0 10100 高位溢出删除,低位补零!

    最后结果:0 10100

    转回十进制就是20

    往左移得到的数字远远比本来的数字大  

    符号位不变,高位溢出删除,低位补零!

    10 << 1(解析:10的二进制数右移1位)

       先算出102进制

       0 0 0 0 1 0 1 0

     0 0 0 0 1 0 1 0     符号位不变,高位溢出删除,低位补零!

     ==============================

       0 0 0 1 0 1 0 0    20

    0*21次方=0

    1* 22次方=4

    0*23次方=0

    1*24次方=16

    所以0+0+4+0+16=20

    举个例子:5<<2 (解析:把五的二进制数右移两位)

    先算出5 的二进制:

    0   101   左移两位,符号位不变

    0 10100 高位溢出删除,低位补零!

    最后结果:0 10100

    转回十进制就是20

    如果是负数就是先转码然后位移

    总结:

    算术右移(往右移得到的数字远远比本来的数字小

    算术左移(往左移得到的数字远远比本来的数字大  

    所以要想得到比本身转换二进制的那个数字大的话 就往左移

    要想得到比本身转换二进制的那个数字小的话 就往右移

    如果是负数就是先转码然后位移

    逻辑右移 >>>

    又叫无符号右移

    不管符号位!低位溢出删除,高位补零!

    所以呢,,逻辑右移的其值永远是正数,剩下的跟算术右移大同小异

    无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位  无符号右移运算符>>> 只是对32位和64位的值有意义

    按位与 &

     两位都为1,结果为1

    5&3

    5 二进制:101

    3 二进制:011

    101

    & 011

    001

    结果为1

    按位或 |

     两位有一位为1,结果为1

    5|3

    5 二进制:101

    3 二进制:011

    101

    | 011

    111

    结果为:7

    按位异或 ^

     必须是一位是0,一位是1,结果才为1

    5^3

    5 二进制:101

    3 二进制:011

    101

    ^ 011

    110

    结果是:6

    按位取反

    ~3

    3 二进制:0 011

    整体取反  1 100

    负数。。。补码转原码,原码转十进制

    -1取反:011 100

    符号位为1,所以最后值:-4

    有个规律:就是数值+1之后取相反的值

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    百度百科目录导航树小插件
    Docker for windows部署mysql挂载数据卷
    ASP.NET CORE 2.0 不小心踩得坑
    获取MVC中Controller下的Action参数异常
    DataTableToList
    svn禁止提交的文件
    plush
    解决端口号被占用的问题
    vue-router
    vue-layer
  • 原文地址:https://www.cnblogs.com/3020815dzq/p/9297913.html
Copyright © 2020-2023  润新知