进制转换(移位运算法)

我们曾在《计算机组成原理》这门课中学习过进制转换的相关知识,在这之前,我们应该首先了解一下原码、反码和补码。根据我们以前在《计算机组成原理》学到的知识,我们知道对于正数和负数,他们的原码、反码、补码是不一样的。

一、原码、反码、补码

  对于正数而言,原码、反码、补码都是一样的,其中最高位表示符号位,因为是正数,所以符号位是0,其他位置是该数的数值位

  对于负数而言,其原码的最高位是符号位1,其他位置是数值位;它的反码是除了符号位以外的其他位置全部按位取反;补码是在其反码的基础上加1;

其中因为对于一个数来说,它的补码的符号位是可以和数值位一起参与加减乘除运算的,所以在计算机中,存储一个数的时候,都是以补码的形式存储的。

上面反码、原码、补码都是一个数的二进制形式,说完这些,再来说进制转换。

二、进制转换

  对于二进制、十进制、八进制、十六进制来说,它们之间的相互转换,其实都是以二进制数作为中间过渡的,比如:

    十进制转换为八进制,先将十进制数转为二进制形式,然后将二进制从右向左每三位一组合并为一个八进制数,例如10转为为八进制表示:

十进制:10
二进制:1010
八进制:12

    八进制转换十六进制,同样也是先转换为二进制,再转换为十六进制,其中八进制转换为二进制的时候,注意由于二进制转换为八进制的时候,是从右到左每三位一组转为八进制数,那么八进制转换为二进制的时候也要使得八进制数从右到左的每一位转换成三位二进制数。然后二进制转换为十六进制的时候,就是从右往左每四位一组合并成一个十六进制数。

三、在Java中表示二进制、八进制、十六进制

在Java中表示一个二进制、八进制、十六进制数是有规定的,它们的具体的形式如下:

  二进制: 由0和1两个数字组成;
  八进制: 由0-7数字组成,为了区分与其他进制的数字区别,必须以0开头,比如,十进制的8,用八进制表示是010;
  十进制: 都是以0-9这九个数字组成,不能以0开头;
  十六进制:由0-9和A-F组成。为了和其他进制的数字进行区分,开头都是以0x或0X开始。

四、移位操作

  移位操作符操作的运算对象是二进制的“位”,并且只能用来操作整数类型,,移位操作符一共有四种:

  1、<<    左移位操作符

    value << num     value是运算对象,num是要向左进行移位的位数,左移的时候在低位补0。其实左移n 位,就相当于乘以2 的n 次方。

  2、>>    有符号右移位操作符

    value >> num    value是运算对象,num是要向右进行移位的位数,右移动的时候,如果原来符号为正,那么在高位插入0;如果原来符号为负,那么在高位插入1。

  3、>>>   无符号右移位操作符

    value >>> num    value是运算对象,num是要向右进行移位的位数,右移动的时候,无论正负,都在高位插入0;其实右移n 位,就相当于除以2 的n 次方。

练习:力扣405题

题目:给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用补码运算方法。

注意:

十六进制中所有字母(a-f)都必须是小写。
十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。 
给定的数确保在32位有符号整数范围内。
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。

分析思路:

 十进制数转换为十六进制数,借助二进制数,从右向左,二进制数每四位合并为十六进制数的一位,所以依次从输入数的二进制形式右边每次取出四位数计算出数值作为十六进制数的一位,然后,将二进制数向右进行移动四位,高位要补0,所以采用无符号右移位操作符,直到最终二进制形式的数变为0。

具体实现如下:

    public String toHex(int num) {
        if (num == 0){
            return "0";
        }
        char[] c = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

        StringBuilder sb = new StringBuilder();
        
        while (num != 0){
            sb.append(c[num & 0b1111]);
            num >>>= 4;
        }
        return sb.reverse().toString();
    }

 

注意,对于byte或者short类型的值,最好不要将无符号右移位操作符和等号组合使用。

 

posted @ 2020-05-28 22:11  有心有梦  阅读(2930)  评论(1编辑  收藏  举报