计算机进制、位运算

一、进制转换

1、什么是进制

进制是数学中的一个概念,就是数据“逢几进位”。进制就是进位制,是人们规定的一种进位方法。对于任何一种进制X,就表示某一位置上的数运算时逢X进一位。二进制就是逢二进一,八进制就是逢八进一,十进制就是逢十进一,十六进制就是逢十六进一。
Java中对整数常量提供了4种表现形式:二进制、八进制、十进制、十六进制。

2、为什么有二进制、八进制、十六进制

有二进制的原因是因为计算机最底层的电子元器件只有两种状态——高电平和低电平(有电和没电)。任何数据在计算机中都是以二进制的形式存在的,二进制早期由电信号开关演变而来的。一个整数在内存中一样也是二进制的,但是使用一大串的1或者0组成的数值进行使用很麻烦!有八进制、十六进制的原因是二进制表示同样的数值太长不方便阅读和记忆,二八进制和十六进制较短,方便阅读和记忆。

3、计算机中存储单位的换算

bit(比特):二进制每一位都是一个bit,二进制只能是0或1两个数字组成,比特是计算机中一个最小的信号单位。
byte(字节):一个bit只能表示两种信号或者两种状态,表示的范围很小!英文字母就有26个,还有标点符号,所以国际化标准组织就规定8个bit为一组,用来表示一个信息单元,是最小的信息单位。
8bit = 1byte
1kb = 1024byte
1mb = 1024kb
1gb = 1024mb
1tb = 1024gb

4、不同进制的组成

二进制是由0,1组成。以0b开头。
八进制是由0~7组成,以0开头。
十进制是由0~9组成,整数默认是十进制的1。
十六进制是由0~9和a~f(大小写都可以),以0x开头。(a=10,b=11,c=12,d=13,e=14,f=15)
public class Test1 {
    public static void main(String[] args) {
        int a = 100;
        System.out.println(a);
        System.out.println("------------------------------");
        int b = 0b100;
        System.out.println(b);
        System.out.println("------------------------------");
        int c = 0100;
        System.out.println(c);
        System.out.println("------------------------------");
        int d = 0x100;
        System.out.println(d);
        System.out.println("------------------------------");
    }
}

5、任意进制转十进制

先了解几个概念:
  • 系数:每一个位上的数字(如:157,个位上的系数是7,十位上的系数是5,百位上的系数是1)。
  • 基数:几进制的基数就是几(十进制的基数就是10)。
  • 权:一个数据从右往左数,从0开始,对每一位数据进行编号,这个编号就是这个位置上的数字的权。
任意进制转十进制的规律:
  • 任意进制到十进制的转换都等于这个数据各个位上的系数 * 基数的权次幂相加的和。
如二进制(0b110)转为十进制: 0 ∗ 2 0 + 1 ∗ 2 1 + 1 ∗ 2 2 = 0 + 2 + 4 = 6 0*2^0 + 1*2^1 + 1*2^2 = 0 + 2 + 4 = 6 020+121+122=0+2+4=6
如八进制(0110)转为十进制: 0 ∗ 8 0 + 1 ∗ 8 1 + 1 ∗ 8 2 = 0 + 8 + 64 = 72 0*8^0 + 1*8^1 + 1*8^2 = 0 + 8 + 64 = 72 080+181+182=0+8+64=72
如十六进制(0XABC)转为十进制: 12 ∗ 1 6 0 + 11 ∗ 1 6 1 + 10 ∗ 1 6 2 = 12 + 176 + 2560 = 2748 12*16^0 + 11*16^1 + 10*16^2 = 12 + 176 + 2560 = 2748 12160+11161+10162=12+176+2560=2748

6、十进制转任意进制

规律:十进制数除目标基数取余数,直到商为0,余数反转。
如十进制(100)转为二进制:

在这里插入图片描述

如十进制(100)转为八进制:

在这里插入图片描述

如十进制(200)转为十六进制:

在这里插入图片描述

7、其他进制之间转换

以十进制作为桥梁,进行转换。如想将二进制转为八进制的步骤:
  • 首先将二进制转为十进制。
  • 再将十进制转为八进制即可。

二、有符号数据表示法

1、有符号数定义

就是数据有正负之分就是有符号数,数据无正负之分就是无符号数据。如:+7、-7就是有符号数。

2、有符号数的组成

符号位 + 数值位(如:int i = +7;在计算机中表示0 0000000000000000000000000000111),java中int占4byte也就是32bit,左边第一位表示符号位,后面都表示数值位。
public class Test1 {
    public static void main(String[] args) {
        //+7的二进制位
        int i = 0b00000000000000000000000000000111;
        System.out.println(i);
        /**
         * 根据符号位表示正负可知,-7的二进制位是0b10000000000000000000000000000111,
         * 但是输出的结果却是-2147483641,这是因为计算机中存储有符号数的时候是按照补码
         * 形式存储的。
         */
        int j = 0b10000000000000000000000000000111;
        System.out.println(j);
    }
}

3、为什么要有有符号数

因为在计算机内,有符号数有三种表示法原码、反码、补码而且所有数据的运算都是采用补码进行的。

4、什么是原码

就是二进制定点表示法,即最高位为符号位,0表示正,1表示负,其余位表示数值的大小。
注意:正数的原码、反码、补码都是一样的;负数的原码、反码、补码是不一样的。

5、什么是反码

反码就是除符号位不变,其它位全部0变为1,1变为0。正数的反码与其原码相同,负数的反码是对其原码逐位取反。

6、什么是补码

补码就是在反码的基础上+1就是补码。
+7的原码为:0b00000000000000000000000000000111
+7的反码为:0b00000000000000000000000000000111
+7的补码为:0b00000000000000000000000000000111
-7的原码为:0b10000000000000000000000000000111
-7的反码为:0b11111111111111111111111111111000
-7的补码为:0b11111111111111111111111111111001
public class Test1 {
    public static void main(String[] args) {
        //+7的二进制位
        int i = 0b00000000000000000000000000000111;
        System.out.println(i);
        /**
         * 根据符号位表示正负可知,-7的二进制位是0b10000000000000000000000000000111,
         * 但是输出的结果却是-2147483641,这是因为计算机中存储有符号数的时候是按照补码
         * 形式存储的。
         */
        // -7的原码为:0b10000000000000000000000000000111
        // -7的反码为:0b11111111111111111111111111111000
        // -7的补码为:0b11111111111111111111111111111001
        int j = 0b11111111111111111111111111111001;
        /**
         * 计算机在显示的时候,会把补码转为原码,转换步骤如下:
         * 1、先将补码-1得到反码
         * 2、反码除符号位不变,其他为0变1,1变0,得到原码
         */
        System.out.println(j);
    }
}

三、位运算

1、位运算概述

位指的是二进制位或者是bit位。计算机中所有的计算到计算机底层中都会变成位运算(就是二进制位的运算)。位运算可以提高程序的效率。

2、位运算符的种类

位运算符连接的操作数是数值类型(底层是二进制),位运算表达式的结果仍然是数值类型。
&:按位与两个同为1的时候结果才为1,否则结果为0。
|:按位或两个中只要有一个1,那么结果就为1,否则结果为0。
^:按位异或两个不一样的时候结果才为1,如果一样,结果就为0。一个数异或两次值不变。
~:按位取反与逻辑非是一样的,1变为0,0变为1。
<<:左移符号位保留不变,数据位左移几位,低位补0。字面上也就是操作数乘以2的n次幂。
>>:右移符号位保留不变,数据位右移几位,高位补符号位,即正数补0,负数补1。除2的n次幂。
>>>:无符号右移数据位右移几位,左边空位都补0(包括符号位),负数会变成正数。
注意:&、|、^是双目运算符,操作数有两个;~是单目运算符,操作数只有一个。
public class Test2 {
    public static void main(String[] args) {
        /**
         * 按位与:3 & 4结果是多少
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 3的二进制:0b00000000000000000000000000000011
         * 4的二进制:0b00000000000000000000000000000100
         * 3&4:     0b00000000000000000000000000000000
         */
        System.out.println("3 & 4 = " + (3 & 4));

        /**
         * 按位或:3 | 4结果是多少
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 3的二进制:0b00000000000000000000000000000011
         * 4的二进制:0b00000000000000000000000000000100
         * 3|4:     0b00000000000000000000000000000111
         */
        System.out.println("3 | 4 = " + (3 | 4));

        /**
         * 按位异或:3 ^ 4结果是多少
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 3的二进制:0b00000000000000000000000000000011
         * 4的二进制:0b00000000000000000000000000000100
         * 3^4:     0b00000000000000000000000000000111
         */
        System.out.println("3 ^ 4 = " + (3 ^ 4));

        /**
         * 按位取反:~3是多少
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 3的二进制:0b00000000000000000000000000000011
         * ~3:      0b11111111111111111111111111111100 负数
         * 已知补码求原码:补码-1之后取反
         * 补码:0b11111111111111111111111111111100
         * -                                     1
         * ---------------------------------------
         * 反码:0b11111111111111111111111111111011
         * 原码:0b10000000000000000000000000000100
         */
        System.out.println("~3 = " + (~3));
    }
}

左移运算:

public class Test3 {
    public static void main(String[] args) {
        /**
         * 左移:3<<2
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 规则:符号位会被保留,数据位左移两位,低位补0
         * 3的二进制:0b00000000000000000000000000000011
         * 3<<2:    0b00000000000000000000000000001100
         */
        System.out.println("3 << 2 = " + (3 << 2));
        System.out.println(0b00000000000000000000000000001100);

        /**
         * 左移:-3<<2
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 规则:符号位会被保留,数据位左移两位,低位补0
         * -3的原码: 0b10000000000000000000000000000011
         * -3的反码: 0b11111111111111111111111111111100
         * -3的补码: 0b11111111111111111111111111111101
         * -3<<2:   0b11111111111111111111111111110100
         */
        System.out.println("-3 << 2 = " + (-3 << 2));
        System.out.println(0b11111111111111111111111111110100);
    }
}

右移运算

public class Test4 {
    public static void main(String[] args) {
        /**
         * 右移:3>>2
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 规则:符号位保留不变,数据位右移2位,高位补符号位
         * 3的二进制:0b00000000000000000000000000000011
         * 3>>2:    0b00000000000000000000000000000001
         */
        System.out.println("3 >> 2= " + (3 >> 2));
        System.out.println(0b00000000000000000000000000000000);

        /**
         * 右移:-3>>2
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 规则:符号位保留不变,数据位右移2位,高位补符号位
         * -3的原码: 0b10000000000000000000000000000011
         * -3的反码: 0b11111111111111111111111111111100
         * -3的补码: 0b11111111111111111111111111111101
         * -3>>2:   0b11111111111111111111111111111111
         */
        System.out.println("-3 >> 2 = " + (-3 >> 2));
        System.out.println(0b11111111111111111111111111111111);
    }
}

无符号右移运算:

public class Test5 {
    public static void main(String[] args) {
        /**
         * 无符号右移:3>>>2
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 规则:数据位右移2位,左边空位都补0(包括符号位),负数会变成正数
         * 3的原码:  0b00000000000000000000000000000011
         * 3>>>2:   0b00000000000000000000000000000000
         */
        System.out.println("3 >>> 2= " + (3 >>> 2));
        System.out.println(0b00000000000000000000000000000000);

        /**
         * 无符号右移:-3>>>2
         * 在进行位运算的时候要把数据转为二进制位,并且全部都是二进制补码形式!
         * 规则:数据位右移2位,左边空位都补0(包括符号位),负数会变成正数
         * -3的原码: 0b10000000000000000000000000000011
         * -3的反码: 0b11111111111111111111111111111100
         * -3的补码: 0b11111111111111111111111111111101
         * -3>>>2:  0b00111111111111111111111111111111
         */
        System.out.println("-3 >>> 2 = " + (-3 >>> 2));
        System.out.println(0b00111111111111111111111111111111);
    }
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值