Java基础之进制转换和位运算

进制转换

什么是进制

进制也就是进位计数制,是人为定义的带进位的计数方法(有不带进位的计数方法,比如原始的结绳计数法,唱票时常用的“正”字计数法,以及类似的tally mark计数)。 对于任何一种进制—X进制,就表示每一位置上的数运算时都是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。

Java针对整数变量提供了4种表现形式

  • 二进制

  • 八进制

  • 十进制

  • 十六进制

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

有二进制的原因是因为计算机最底层的电子元器件只有两种状态–高电平和低电平(有电和没电)。任何数据在计算机中都是以二进制的形式存在的,二进制早期由电信号开关演变而来。一个整数在内存中一样也是二进制的,但是使用一大串的1或者0组成的数值进行使用很麻烦!

有八进制、十六进制的原因是因为二进制表示同样的数值太长不方便阅读和记忆,而八进制和十六进制较短,方便阅读和记忆。

ASCII 奥斯卡码值1个字节 八位可以表示256不同个字符

计算机中存储单位的换算

  • 8bit=1byte

  • 1kb=1024byte

  • 1mb=1024kb

  • 1gb=1024mb

  • 1tb=1024gb

什么是bit?

二进制:001 每一位就是bit,二进制只能是0/1两种数字组成,是计算机中一个最小的信号单位,可能是高电平也可能是低电平

什么是byte?

1个bit只能表示两种信号或者两种状态,表示的范围很小!因为咱们英文字母就有26个,两种状态很明显不够表示。所以国际标准化组织就规定把8个bit归为一组数据的最小单元!

不同进制的组成

  • 二进制

    • 有0,1组成。以0b开头(不区分大小写)
  • 八进制

    • 由0,1,2…7组成。以0开头
  • 十进制

    • 由0,1,2…9组成。整数位默认是十进制的
  • 十六进制

    • 由0,1,2…,a,b,c,d,e,f(大小写均可)。以0x开头(不区分大小写)

**注意:**进制位计算也是从0开始的

	//演示100在各个进制之间的值
    public static void main(String[] args) {
        int a = 0b100;//二进制
        int b = 0100;//八进制
        int c = 100;//十进制
        int d = 0x100;//十六进制
        System.out.println("二进制:"+a+"\t八进制:"+b+"\t十进制:"+c+"\t十六进制:"+d);
		//结果为:二进制:4(2^2)	八进制:64(8^2)	十进制:100(默认)	十六进制:256(16^2)
    }

不同进制数据之间的计算

十进制数据之间的计算

10+10=20

二进制数据之间的计算

0b1101+0b1101010=0b1110111

八进制数据之间的计算

0127+0765=01114

十六进制数据之间的计算

(a=10,b=11,c=12,d=13,e=14,f=15)

0x1ab+0x99a=0xb45

练习

ob1110111-0b1111010=?
01765-043211=?
0x1fffa-0x2ffab=?

进制转换

  • 系数:每一个位上的数字,例如157,个位系数为7、十位系数为7、百位系数为1

  • 基数:就是进制数,几进制基数就是几,10进制基数就是10

  • 权:一个数据从右往左数,从0开始,对每一位数据进行编号,那么这个编号就是这个位置上的数字的系数

任意进制到十进制的转换

**公式:**这个数据的各个位上的系数乘以基数的权次幂相加的和

-- 任意进制转换成十进制
0b111=1*2^0+1*2^1+1*2^2=1+2+4=7
0110=0*8^0+1*8^1+1*8^2=0+8+64=72
0xabc1=1*16^0+12*16^1+11*16^2+10*16^3=1+192+2816+40960=43969

十进制到其他进制的转换

**公式:**用这个数字除基数取余数,直到商为0,余数反转

十进制到其他进制之间的转换

-- 把十机制的100转换为其他进制
-- 十进制转二进制
100=0b1100100
-- 十进制转八进制
100=0144
-- 十进制转十六进制
100=0x64

十进制和二进制之间的快速转换

**8421码:**8421码是中国大陆的叫法,8421码是BCD码中最常用的一种。在这种编码方式中每一位二进制代码的1都是代表一个固定数值,把每一位的1代表的十进制数加起来,得到的结果就是它所代表的十进制数码。

**BCD码:**BCD 码(Binary-Coded Decimal〉亦称二进码十进数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数码。是一种二进制的数字编码形式,用二进制编码的十进制代码。

BCD码展示:

二进制:11111111
十进制:1286432168421

二进制和八进制、十六进制如何转换

  • 以十进制为桥梁

  • 二进制到八进制3位组合

  • 二进制到十六进制4位组合

有符号数据表示法

什么是有符号数

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

有符号数组成

这里声明一点,必须要记住:计算机存储的数据永远是补码!!!

符号位+数值位(例如:int i=+7)

为什么要有符号数?

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

什么是原码?

就是二进制定点表示法,即最高位为符号位,"0"表示正,"1"表示负,其余为表示数值的大小。

什么是反码?

正数的反码与其原码相同,负数的方法是对其原码逐位取反,但符号位除外。

什么是补码?

补码就是在反码的基础上加1

代码示例

package com.edu.baseAndBitOperations.base;

/**
 * 正数和负数是怎么在计算机中进行出储存的
 *
 * @作者 five-five
 * @创建时间 2021/4/16
 */
public class Demo03 {
    public static void main(String[] args) {
        //+7、-7在计算机中是如何储存的
        //有符号数有两部分组成:1.符号位:最高值表示符号,0为正,1为负   2.数值位
        //int的范围:-2的31次方~2的31次方-1(因为有一位是符号位)
//        int i=7;//+7
        //7:0b0000000000,0000000000,0000000001,11
        int i=0b00000000000000000000000000000111;
        System.out.println(i);

        //int j=-7;//-7
        //0b10000000000000000000000000000111;
        //计算机存储有符号数的时候是按照补码的形式存进去的
        //0b10000000000000000000000000000111;不是二进制的补码,而是二进制的原码
        //计算机有符号数据都是按照补码的形式存进去的

        //正数的原码反码补码都一样,负数的原码反码补码是不一样的
        //什么是原码:就是符号位+数值位
        //什么是反码:除符号位不变,其他位全部1变0,0变1
        //什么是补码:补码就是在反码的基础上加1
        /*

            +7:
                原码:0b0,00000000,00000000,00000000,00001,11
                反码:0b0,00000000,00000000,00000000,00001,11
                补码:0b0,00000000,00000000,00000000,00001,11

            -7:
                原码:0b1,00000000,00000000,00000000,00001,11
                反码:0b1,11111111,11111111,11111111,11110,00
                补码:0b1,11111111,11111111,11111111,11110,01
         */
        int j=0b11111111111111111111111111111001;//-7
        System.out.println(j);
        //计算机在显示给我们看的时候,会把补码转换为原码
        //怎么转:补码-1变成反码,剩下的除符号位不变,其余的0变1,1变0
    }
}

位运算(位指的是二进制位或者是bit位)

计算机中所有的订算到计算机底层中都会变成位运算(就是二进制位的运算)。位运算可以提高程序的效率!而且以后如果我们研究JDK或者某个框架的原码,会发现很多地方都用到了位运算!

位运算的种类

  • **&**:按位与,规则:两个同为1时才为1

  • **|**:按位或,规则:只要上下有一方为1的时候,就等于1

  • **^**:按位异或,规则:两个中不一样的时候才为1,如果一样就为0

  • **~**:按位取反,规则:1变0,0变1

  • **<<**:左移,规则:让操作数乘以2的n次幂,n就是移动的位移

  • **>>**:右移,规则:让操作数除以2的n次幂,n就是移动的位移

  • **>>>**:无符号右移,规则:操作数除以2的n次幂,用0补全空位

  • 无符号右移**>>>**和右移**>>**的区别是:

    • **>>**右移操作之后左边会有空位置出来且空位置用该操作数的符号位置的数补全

    • **>>>**无符号右移之后左边会有空位置出来且空位置用0补全

注意:进行位运算的时候,所有的操作数全部都是二进制,并且是补码!!!

代码示例

&、|、、~位运算符的操作和理解,(按位与&、按位或|、按位异或、按位取反~)

package com.edu.baseAndBitOperations.base;

/**
 * 位运算符的操作和理解,(按位与&、按位或|、按位异或^、按位取反~)
 * 注意:进行位运算的时候,所有的操作数全部都是二进制,并且是补码!!!
 *
 * @作者 five-five
 * @创建时间 2021/4/16
 */
public class Demo04 {
    /*
        &:按位与,只有上下都为1的时候,才等于1
        |:按位或,只要上下有一方为1的时候,就等于1
        ^:按位异或,两个中不一样的时候才为1,如果一样就为0
        ~:按位取反,1变0,0变1
        <<:左移,让操作数乘以2的n次幂,n就是移动的位移
        >>:右移,让操作数除以2的n次幂,n就是移动的位移
        >>>:无符号右移,操作数除以2的n次幂,用0补全空位

     */
    public static void main(String[] args) {
        //注意:在进行位运算时时候要把数据转换成二进制位!并且全部都是二进制的补码形式。
        //按位与:&,只有上下都为1的时候,才等于1
        //3&4的结果
        //3:0b0000000000,0000000000,0000000000,11
        //4:0b0000000000,0000000000,0000000001,00
        //3&4:0b0000000000,0000000000,0000000000,00
        System.out.println(3 & 4);//0

        //注意:在进行位运算时时候要把数据转换成二进制位!并且全部都是二进制的补码形式。
        //按位或:|,只要上下有一方为1的时候,就等于1
        //3|4的结果
        //3:0b0000000000,0000000000,0000000000,11
        //4:0b0000000000,0000000000,0000000001,00
        //3|4:0b0000000000,0000000000,0000000001,11
        System.out.println(3 | 4);//7

        //注意:在进行位运算时时候要把数据转换成二进制位!并且全部都是二进制的补码形式。
        //按位异或:^,两个中不一样的时候才为1,如果一样就为0
        //3^4的结果
        //3:0b0000000000,0000000000,0000000000,11
        //4:0b0000000000,0000000000,0000000001,00
        //3^4:0b0000000000,0000000000,0000000001,11
        System.out.println(3 ^ 4);//7

        //注意:在进行位运算时时候要把数据转换成二进制位!并且全部都是二进制的补码形式。
        //按位取反:~,1变0,0变1
        //~4的结果
        //4:0b0000000000,0000000000,0000000001,00
        //~4:0b11111111111111111111111111111110,11(相当于补码)
        //反码:0b11111111111111111111111111111110,10(补码-1=反码)
        //源码:0b10000000000000000000000000000001,01(反码取反=原码)
        System.out.println(~4);//-5
    }
}

按位异或的常见应用

package com.edu.baseAndBitOperations.base;

/**
 * ^:按位异或,两个中不一样的时候才为1,如果一样就为0
 * 按位异或^的常见应用:一个数据对相同的数据异或两次其值不变
 *
 * @作者 five-five
 * @创建时间 2021/4/16
 */
public class Demo05 {
    public static void main(String[] args) {
        /*
            数据a
            数据b
            a两次异或b 结果还是a
            a^b^b=a
         */
        int a = 2;
        int b = 3;
        //2:0b00000000,00000000,00000010
        //3:0b00000000,00000000,00000011
    //a=2^3:0b00000000,00000000,00000001
      //a^3:0b00000000,00000000,00000010
        int temp = a ^ b;
        temp ^= b;
        System.out.println(a ^ b ^ b);
        System.out.println(temp);
    }
}

<<、>>、>>>位运算符的操作和理解,(左移<<、右移>>、无符号右移<<<)

package com.edu.baseAndBitOperations.base;

/**
 * 位运算符的操作和理解,(左移<<、右移>>、无符号右移<<<)
 * 注意:进行位运算的时候,所有的操作数全部都是二进制,并且是补码!!!
 *
 * @作者 five-five
 * @创建时间 2021/4/16
 */
public class Demo06 {
    /*
       &:按位与,只有上下都为1的时候,才等于1
       |:按位或,只要上下有一方为1的时候,就等于1
       ^:按位异或,两个中不一样的时候才为1,如果一样就为0
       ~:按位取反,1变0,0变1
       <<:左移,让操作数乘以2的n次幂,n就是移动的位移
       >>:右移,让操作数除以2的n次幂,n就是移动的位移
       >>>:无符号右移,操作数除以2的n次幂,
       无符号右移和右移的区别是:
            右移操作之后左边会有空位置出来且空位置用该操作数的符号位置的数补全
            无符号右移之后左边会有空位置出来且空位置用0补全
       格式:操作数<<往左移动的位数
            操作数>>往右移动的位数
            操作数>>>往右移动的位数
    */
    public static void main(String[] args) {
        //左移 <<
        int i = 3;
        //3:0b00000000,00000000,00000000,00000011
        //3<<2:0b000000,00000000,00000000,0000001100(往左边移动两位,左边的两位就被挤掉了,右边就空出两位用0补全)
        System.out.println(i << 2);//3*2^2

        //右移 >>
        int j = 32;
        //32:0b00000000,00000000,00000000,00100000
        //32>>2:0b00000000,00000000,00000000,00001000(往右边移动两位,左边就空出两位,右边的两位就被挤掉了,左边空出的位置用符号位的值填充)
        System.out.println(j >> 2);//32/(2^2)

        //-32:0b10000000,00000000,00000000,00100000(原码)
        //-32:0b11111111,11111111,11111111,11011111(反码)
        //-32:0b11111111,11111111,11111111,11100000(补码)
        //-32>>2:0b11111111,11111111,11111111,11100000
        //(往右边移动两位,左边就空出两位,右边的两位就被挤掉了,左边空出的位置用符号位的值填充)
        //-32>>2:0b1111111111,11111111,11111111,111000(补码)
        //-32>>2:0b1111111111,11111111,11111111,110111(反码)
        //-32>>2:0b1000000000,00000000,00000000,001000(原码)
        System.out.println(-j >> 2);//-32/(2^2)
        System.out.println(0b11111111111111111111111111111000);//-32/(2^2)

        //无符号右移 >>>
        int k = 32;
        //32:0b00000000,00000000,00000000,00100000
        //32>>>2:0b00000000,00000000,00000000,00001000(往右边移动两位,左边就空出两位,右边的两位就被挤掉了,左边空出的位置用0填充)
        System.out.println(k >>> 2);//32/(2^2)
        //-32:0b10000000,00000000,00000000,00100000(原码)
        //-32:0b11111111,11111111,11111111,11011111(反码)
        //-32:0b11111111,11111111,11111111,11100000(补码)
        //32>>>2:0b0011111111,11111111,11111111,111000(往右边移动两位,左边就空出两位,右边的两位就被挤掉了,左边空出的位置用0填充)
        System.out.println(-k >>> 2);
        System.out.println(0b00111111111111111111111111111000);
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Java中实现任意转换,可以使用以下示例代码: ```java public class BaseConversion { public static String decimalToBase(int number, int base) { if (base < 2 || base > 36) { throw new IllegalArgumentException("基数必须在2到36之间"); } StringBuilder result = new StringBuilder(); while (number > 0) { int remainder = number % base; if (remainder < 10) { result.insert(0, remainder); } else { char digit = (char) ('A' + remainder - 10); result.insert(0, digit); } number /= base; } return result.toString(); } public static int baseToDecimal(String number, int base) { if (base < 2 || base > 36) { throw new IllegalArgumentException("基数必须在2到36之间"); } int result = 0; for (int i = number.length() - 1; i >= 0; i--) { char digit = number.charAt(i); int value = Character.isDigit(digit) ? digit - '0' : digit - 'A' + 10; result += value * Math.pow(base, number.length() - 1 - i); } return result; } public static void main(String[] args) { int number = 255; int base = 16; // 十转换为十六 String result1 = decimalToBase(number, base); System.out.println(number + "转换为" + base + ":" + result1); String binaryNumber = "101010"; int binaryBase = 2; // 二转换为十 int result2 = baseToDecimal(binaryNumber, binaryBase); System.out.println(binaryNumber + "转换为十:" + result2); } } ``` 在这个示例中,我们实现了两个静态方法:`decimalToBase`用于将十转换为任意,`baseToDecimal`用于将任意转换为十。 `decimalToBase`方法接收两个参数:`number`表示要转换的十数,`base`表示目标。它使用模运算和除法运算来逐步计算出每一位的值,并将结果存储在StringBuilder中,最后返回转换后的字符串。 `baseToDecimal`方法接收两个参数:`number`表示要转换的任意数(以字符串形式表示),`base`表示原始。它遍历每一位字符,根据字符的值计算出对应的数值,并根据权重求和,最后返回转换后的十数。 在main方法中,我们演示了将十数255转换为十六以及将二数101010转换为十的示例。运行这段代码,你会看到以下输出结果: ``` 255转换为16:FF 101010转换为十:42 ``` 请注意,这只是一个简单的实现示例,对于更大范围的数值或更高的可能需要更复杂的算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

five-five

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值