最清晰的进制转换讲解 - java实现
子曰:知之为不知,不知为不知,太菜也!
进制转换在平时的算法练习题或者项目中都会遇到,下面我们来看一下使用java如何进行进制互相转换。
文章目录
- 1. 使用内置函数进行进制转换
- 十进制转换其他进制
- 其他进制转换十进制
- 2. 模运算
- 十进制到任意进制的转换
- 任意进制到十进制数的转换
- 3. 位运算
1. 使用内置函数进行进制转换
在java函数中,Integer
类中已经有相应函数可以进行十进制 与 二进制,八进制和十六进制的转换。
十进制转换其他进制
//十进制转成二进制 Integer.toBinaryString(int i) //十进制转成八进制 Integer.toOctalString(int i) //十进制转成十六进制: Integer.toHexString(int i)
其他进制转换十进制
//二进制转十进制 Integer.valueOf("10111",2).toString()//八进制转成十进制 Integer.valueOf("188",8).toString() //十六进制转成十进制 Integer.valueOf("ABC",16).toString()
使用java提供的函数进行进制转换只能进行二进制,八进制,十进制和十六进制间的转换,这可能还不能满足我们的需求,那么如何实现任意进制的转换呢。
2. 模运算
可以使用离散数学的模运算来进行进制的转换。具体的计算过程这里就不赘述了,下面是相应代码。
十进制到任意进制的转换
public static String Dec2Any(int n, int k) {// 存放取模的栈Stack s = new Stack<Integer>();// 用来储存结果串StringBuffer result = new StringBuffer("");// 对十进制数字进行取模运算,余数压栈,除的结果进入下次循环while (n != 0) {s.push(n % k);n = n / k;}// 将栈中的元素加入string中while (!s.isEmpty())result.append(s.pop());return result.toString();}
上面的代码需要注意一个问题,就是把十进制的数转为超过十进制的数字时,需要用相应的多进制表示符号替换。
任意进制到十进制数的转换
代码如下
public static int Any2Dec(String num,int k){// 最终产生的10进制结果int res = 0;// 用来记录个位,十位,百位...int flag = 0;// 从末尾一直遍历整个字符串(也就是从个位开始到最高位)for (int i = num.length()-1;i >= 0;i--){// 记录相对应的位置上的值int value = num.charAt(i);// 记录此位置上的单位大小,类比10进制就是 个位、十位、百位上的数字分别代表个十百int unit = (int)Math.pow(k, flag++);// 某一位置上的值 = 单价(个十百) * 数字if (num.charAt(i) >= 'A')// 如果大于A表示,超过了10,要还原成数字res += unit * (value -'A'+ 10);elseres += unit * (value -'0');}return res;}
3. 位运算
以前进行进制转换,我也只会想到使用模运算,但是后来通过查看java的Integer中进制转换的源码,发现java内部是使用位运算进行进制转换的。
我们首先看十进制到其他进制的转换,相应函数的源码如下
// 这里的i就是进制对应的二进制表示位数,8就是3位,16进制就是4位public static String toBinaryString(int i) {return toUnsignedString(i, 1);}public static String toOctalString(int i) {return toUnsignedString(i, 3);}public static String toHexString(int i) {return toUnsignedString(i, 4);}
我们可以看到,内部是通过调用了toUnsignedString(int i)
这个函数来实现进制转换的。
/*** 将整数转换为无符号数*/private static String toUnsignedString0(int val, int shift) {// 确保转化位数的值在1-5之间,否则就会报错int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);int chars = Math.max(((mag + (shift - 1)) / shift), 1);if (COMPACT_STRINGS) {byte[] buf = new byte[chars];formatUnsignedInt(val, shift, buf, 0, chars);return new String(buf, LATIN1);} else {byte[] buf = new byte[chars * 2];formatUnsignedIntUTF16(val, shift, buf, 0, chars);return new String(buf, UTF16);}}
这里对其中的一些值进行常亮解释
//用于表示二进制补码形式的值的位数
public static final int SIZE = 32;
numberOfLeadingZeros
函数解释
// 计算i当中第一个不为0的位置,最左边的一位,左边的值(0) < 右边的值(n)public static int numberOfLeadingZeros(int i) {//返回32,如果指定值的补码表示形式中没有1出现if (i <= 0)return i == 0 ? 32 : 0;int n = 31;// 类似于二分法的查找// 如果i大于第十六为1的值,那么n的值在前16位,故 n = n -16// 此时i最左侧的值不会出现在后16位, >>>=16 表示右移的数目为16// 依次地推,直到最后找见1 的最左侧位if (i >= 1 << 16) { n -= 16; i >>>= 16; }if (i >= 1 << 8) { n -= 8; i >>>= 8; }if (i >= 1 << 4) { n -= 4; i >>>= 4; }if (i >= 1 << 2) { n -= 2; i >>>= 2; }return n - (i >>> 1);}
因为我对位运算不是很熟悉,因此看起来还是挺有难度的,这里对函数进行一个解析,以十进制转为十六进制toUnsignedString(i, 4)
为例。
- int radix = 1 << shift这一行,把1左移4位,得到radix为16
- int mask = radix - 1得到mask为15,其二进制形式为00001111
- buf[–charPos] = digits[i & mask]中,i & mask的目的就是取i的最后4位,然后在digits表单中取到相应的十六进制字符。
- i >>>= shift,这一行,抛弃刚处理过的最后4位,往右再推4位,然后进入循环,直到i为0;
所有的十六进制的字符都放在了buf里面,然后组合成一个字符串,返回。
我们可以通过改写这个函数,把十进制的数转换为任意2次方进制的数。
把其他进制转换为十进制时,内部是调用了Integer的parseInt(String s, int radix)
方法。代码如下:
public static int parseInt(String s, int radix)throws NumberFormatException{/** WARNING: This method may be invoked early during VM initialization* before IntegerCache is initialized. Care must be taken to not use* the valueOf method.*/if (s == null) {throw new NumberFormatException("null");}if (radix < Character.MIN_RADIX) {throw new NumberFormatException("radix " + radix +" less than Character.MIN_RADIX");}if (radix > Character.MAX_RADIX) {throw new NumberFormatException("radix " + radix +" greater than Character.MAX_RADIX");}int result = 0;boolean negative = false;int i = 0, len = s.length();int limit = -Integer.MAX_VALUE;int multmin;int digit;if (len > 0) {char firstChar = s.charAt(0);if (firstChar < '0') { // Possible leading "+" or "-"if (firstChar == '-') {negative = true;limit = Integer.MIN_VALUE;} else if (firstChar != '+')throw NumberFormatException.forInputString(s);if (len == 1) // Cannot have lone "+" or "-"throw NumberFormatException.forInputString(s);i++;}multmin = limit / radix;while (i < len) {// Accumulating negatively avoids surprises near MAX_VALUEdigit = Character.digit(s.charAt(i++),radix);if (digit < 0) {throw NumberFormatException.forInputString(s);}if (result < multmin) {throw NumberFormatException.forInputString(s);}result *= radix;if (result < limit + digit) {throw NumberFormatException.forInputString(s);}result -= digit;}} else {throw NumberFormatException.forInputString(s);}return negative ? result : -result;}
核心代码是下面这部分
while (i < len) {// Accumulating negatively avoids surprises near MAX_VALUEdigit = Character.digit(s.charAt(i++),radix);if (digit < 0) {throw NumberFormatException.forInputString(s);}if (result < multmin) {throw NumberFormatException.forInputString(s);}result *= radix;if (result < limit + digit) {throw NumberFormatException.forInputString(s);}result -= digit;}
通过学习Inreger进制转换方法的实现过程,读者可以自己对其进行改造从而实现自己需要完成的功能。毕竟使用位运算进行进制转换的效率会高一些。
版权声明:本文为CSDN博主「胡瓜_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cwfjimogudan/article/details/53087303
你懂了没?
最清晰的进制转换讲解 - java实现相关推荐
- java函数实现进制转换与java实现八进制到十进制的转换(百练OJ:2735:八进制到十进制)
java进制转换函数介绍:Java二进制.八进制.十进制.十六进制相互转换: 二进制转十进制 Integer.parseInt("0110", 2); 八进制转十进制 Intege ...
- 植物大战僵尸 进制转换 使用JAVA 更改关卡 和金钱
文章目录 前言 一.进制转换 将二进制.八进制.十六进制转换为十进制 将二进制.八进制.十六进制转换为十进制 二.获取数据修改关卡 小技巧进制转换 三.获取数据修改阳光 四.通过编码修改关卡和金钱 修 ...
- 进制转换和java基础语法
标题1.软件版本升级的原因 软件版本升级的原因:1.功能增加 2.功能优化 3.修改bug 注意:一般情况,新的版本的软件中的体积会越来越大,新的方法不会覆盖原来的方法 标题2.进制转换 2.1什么是 ...
- java 进制转换工具_进制转换工具(JAVA)
/**进制转换工具,支持2-36任意进制间相互转换 */ public class HexConverter { public static String Quotient = null; publi ...
- java进制转换界面,java进制转换器 图形用户界面 十进制及其相反数诀别转化为二,四,八,十六进制...
java进制转换器 图形用户界面 十进制及其相反数分别转化为二,四,八,十六进制 package com.rgy.Test; import java.awt.Color; import java.aw ...
- java:数据结构(二)栈的应用(进制转换全收集)
说到进制转换,java已经封装了基本的方法,在竞赛中使用封装的方法自然能节省大量时间 另一位仁兄介绍的封装好的方法: https://blog.csdn.net/m0_37961948/article ...
- Java中四种进制转换
进制介绍 举例: 不同进制转换运算 Java中二进制使用0b(0B)前缀来表示,不足一字节需高位补零,凑成8位. Java中八进制使用0前缀来表示. Java中十六进制使用0x(0X)来表示,a~e( ...
- 信号与传输介质和计算机进制转换
1.信号相关的概念 信息 不同领域对信息有不同的定义,一般认为信息是人们对现实世界事物的存在方式或运动状态的某种认识.表示信息的形式可以是数值.文字.图形.声音.图像及动画等. 数据 数据是用于描述事 ...
- 山东专升本—计算机课堂笔记之进制转换
二进制:0 1 八进制:0~7 十进制:0~9 十六进制:0~15 -- 0~9 + A~F(在十六进制 10~15,10后面用字母表示) 进制的数码不可能"=>" ...
最新文章
- pyhon滤镜详细教程
- C# delegate event
- 购买流程图java_Java实现基于控制台的购书系统基本操作
- matlab 程序设计
- javascript对象包含哪些要素_javascript有哪几种对象?
- 深度学习(02)-- ANN学习
- Redis系列四、redis的五种数据结构和相关指令之List
- php7 变量,PHP7变量结构分析
- 9 pcb螺丝焊盘打很多小孔_PCB板设计的10个基本设计流程
- python字符串变量_Python从变量读取的特殊字符切分字符串问题
- 低学历的人就不能创业了吗?
- SAI绘制小树基础教程
- 秒懂!何凯明Resnet
- 多系统对接的实现方案
- 影视后期视频制作系统——非编系统
- Wifidog扫盲篇
- 交换机,路由器和防火墙
- 南华大学计算机系宿舍,2021年南华大学新生宿舍条件和宿舍环境图片
- 标段(包)分类 字典sql
- js(EcamaScript)