zoukankan      html  css  js  c++  java
  • 二进制、原码、补码和位运算的入门

    一、十进制

    • · 每个位置可以有10个数字,从0到9
    • · 每个位置都有一个位权,从右到左,第一位为1,然后依次乘以10,即第二位为10,第三位为100,依次类推,如:

    123表示的1*(10^2) + 2*(10^1) + 3*(10^0),(10^2表示10的二次方),它表示的是各个位置数字含义之和。每个位置的数字含义与位置有关,从右向左,第一位乘以10的0次方,即1,第二位乘以10的1次方,即10,第三位乘以10的2次方,即100,依次类推。

     

    二、二进制

    1. 正整数的二进制表示

    • 每个位置只能是0或1。
    • 位权的概念是类似的,从右到左,第一位为1,然后依次乘以2,即第二位为2,第三位为4,依次类推。
    • 使用符合我们直觉的原码表示法

     

    看一些数字的例子吧:

    二进制

    十进制

    10

    2

    11

    3

    111

    7

    1010

    10

     

    2. 负整数的二进制表示

    1. 十进制的负数表示就是在前面加一个负数符号-,例如-123
    2. 二进制使用最高位表示符号位,用1表示负数,用0表示正数。
    3. 使用补码表示法,补码表示就是在原码表示的基础上取反然后加1。取反就是将0变为1,1变为0。比如:
    • -1:1的原码表示是00000001,取反是11111110,然后再加1,就是11111111。
    • -2:2的原码表示是00000010,取反是11111101,然后再加1,就是11111110
    • -127:127的原码表示是01111111,取反是10000000,然后再加1,就是10000001。

    4. 给定一个负数二进制表示,要想知道它的十进制值,可以采用相同的补码运算。比如:10010010,首先取反,变为01101101,然后加1,结果为01101110,它的十进制值为110,所以原值就是-110。

     

    3. 负整数为什么采用补码呢?

    • · 因为只有这种形式,计算机才能实现正确的加减法。
    • · 计算机其实只能做加法

    比如:1-1其实是1+(-1)。如果用原码表示,计算结果是不对的。

    1   -> 00000001
    
    -1 -> 10000001
    
    + ------------------
    
    -2 -> 10000010 //用符合直觉的原码表示,1-1的结果是-2。

    如果是补码表示:

    1   -> 00000001
    
    -1 -> 111111111
    
    + ------------------
    
    0  ->  00000000 //结果是正确的。

    再比如,5-3:

     

    5   -> 00000101
    
    -3 -> 11111101
    
    + ------------------
    
    2  ->  00000010 //结果也是正确的。

    理解了二进制加减法,我们就能理解为什么正数的运算结果可能出现负数了。当计算结果超出表示范围的时候,最高位往往是1,然后就会被看做负数。比如说,127+1:

    127   -> 01111111
    
    1       -> 00000001
    
    + ------------------
    
    -128  ->10000000

    计算结果超出了byte的表示范围,会被看做-128。

    规律:

    • · 正数的取反等于正数加1取负,例如11的取反等于-12
    • · 负数的取反等于负数加1取正,例如-12的取反等于11

    三、十六进制

    二进制写起来太长,为了简化写法,可以将四个二进制位简化为一个0到15的数,10到15用字符A到F表示,这种表示方法称为16进制,如下所示:

     

    2进制

    10进制

    16进制

    1010

    10

    A

    1011

    11

    B

    1100

    12

    C

    1101

    13

    D

    1110

    14

    E

    1111

    15

    F

     

    • 可以用16进制直接写常量数字,在数字前面加0x即可。比如10进制的123,用16进制表示是0x7B,即123 = 7*16+11。给整数赋值或者进行运算的时候,都可以直接使用16进制,比如:
      • int a = 0x7B;
    • Java中不支持直接写二进制常量,比如,想写二进制形式的11001,Java中不能直接写,可以在前面补0,补足8位,为00011001,然后用16进制表示,即 0x19。

     

    查看整数的二进制和十六进制表示

    在Java中,可以方便的使用Integer和Long的方法查看整数的二进制和十六进制表示,例如:

    int a = 25; 
    
    System.out.println(Integer.toBinaryString(a)); //二进制
    
    System.out.println(Integer.toHexString(a));  //十六进制
    
    System.out.println(Long.toBinaryString(a)); //二进制
    
    System.out.println(Long.toHexString(a));  //十六进制

    四、位运算

    1. 位运算是将数据看做二进制,进行位级别的操作
    2. Java不能单独表示一个位,但是可以用byte表示8位,可以用16进制写二进制常量。比如: 0010表示成16进制是 0x2, 110110表示成16进制是 0x36。
    3. 位运算有移位运算和逻辑运算。

    1. 移位运算:

    • 左移:操作符为<<,向左移动,右边的低位补0,高位的就舍弃掉了,将二进制看做整数,左移1位就相当于乘以2。
    • 无符号右移:操作符为>>>,向右移动,右边的舍弃掉,左边补0。
    • 有符号右移:操作符为>>,向右移动,右边的舍弃掉,左边补什么取决于原来最高位是什么,原来是1就补1,原来是0就补0,将二进制看做整数,右移1位相当于除以2。

    例如:

    int a = 4; // 100
    
    a = a >> 2; // 001,等于1
    
    a = a << 3 // 1000,变为8

    2. 逻辑运算: 

    • 按位与 &:两位都为1才为1
    • 按位或 |:只要有一位为1,就为1
    • 按位取反 ~: 1变为0,0变为1
    • 按位异或 ^ :相异为真,相同为假

    具体形式,例如: 

    int a = ...; 
    
    a = a & 0x1 // 返回0或1,就是a最右边一位的值。
    
    a = a | 0x1 //不管a原来最右边一位是什么,都将设为1
  • 相关阅读:
    第一个android开发,记录三
    第一个android开发,记录二
    第一个android开发,记录一
    第一行代码LitePal的问题
    第二阶段冲刺个人总结5
    PHP中验证码的制作教程
    选项卡的制作代码
    HTML5布局总结篇
    PHP实现简单的计算器
    PHP中的运算符
  • 原文地址:https://www.cnblogs.com/wslook/p/9385349.html
Copyright © 2011-2022 走看看