Java十进制与各进制(2~36)之间转换,代码实现加原理解析 - Go语言中文社区

Java十进制与各进制(2~36)之间转换,代码实现加原理解析


Java 十进制和各进制之间相互转换

话不多说,先上代码

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class NumberBaseUtil {

  public static void main(String[] args) {
    NumberBaseUtil nb = new NumberBaseUtil();
    long number = NumberBaseUtil.toDecimal("1110", 2);
    System.out.println(number);
    System.out.println(NumberBaseUtil.toOtherBase(15, 2));
  }

  // number字符数组
  public static final char[] NUMBER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
      'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
      'V', 'W', 'X', 'Y', 'Z'};
      
 /**
   * 输入任意进制转化为10进制
   * @param value 数值
   * @param numberBase 进制 2~36
   * @return long
   * @Author xiangyuan.liu
   * @Title toDecimal
   */
  public static long toDecimal(String value, int numberBase) {
    //  将数值中开头的0去掉并全部转成大写
    value = value.replaceAll("^(0+)", "").toUpperCase();
    // 初始化map,将字符数组中的按索引存入map,字符相当于key, value相当于十进制的值
    int LEN = NUMBER.length;
    Map<Character, Integer> numberMap = new HashMap<>(LEN);
    for (int i = 0; i < LEN; i++) {
      numberMap.put(NUMBER[i], i);
    }
    // 数值转为字符数组
    char[] sh = value.toCharArray();
    int len = sh.length;
    // 位数
    int n = 0;
    long sum = 0;
    for (char item : sh) {
      // 从后位往前加
      // 根据公式 S = x ** y * z (x代表进制,y代表位数,z代表该位上的值)
      sum += (numberMap.get(item)) * Math.pow(numberBase, len - (n++) - 1);
    }
    return sum;
  }


  /**
   * 10进制转任意进制
   * @param value 10进制数值
   * @param base 目标进制
   * @return java.lang.String
   * @Author xiangyuan.liu
   * @Title toOtherBase
   */
  public static String toOtherBase(long value, int base) {
    StringBuilder str = new StringBuilder();
    Stack<Character> stack = new Stack<>();
    while (value != 0) {
      stack.push(NUMBER[(int) (value % base)]);
      value /= base;
    }
    while (!stack.isEmpty()) {
      str.append(stack.pop());
    }
    return str.toString();
  }
}

测试执行结果,转换正确。
在这里插入图片描述
有些缺陷就是,不能超过long的范围长度而且不支持小数,改进方法就是用BigDecimal类代替long类型。

原理

各进制转10进制

根据公式S = x ** y * z           
  x代表进制,y代表位数(y从右边开始为0),z代表该位上的值,然后将各个位算出的S累加起来
  例如8进制转10进制:
  八进制 30102, 则x=8,y分别为0,2,4;z为3,1,2
转换为十进制为:
   8 ** 0 * 2 + 8 ** 2 * 1 + 8 ** 4 * 3 = 12354
    2        +       64      +     12,288  = 12354

sum += (numberMap.get(item)) * Math.pow(numberBase, len - (n++) - 1);
从map中取出的相当于10进制的值z, 然后从右边开始乘于进制的位数次方,累加起来就可以得到10进制的值。

 public static long toDecimal(String value, int numberBase) {
    //  将数值中开头的0去掉并全部转成大写
    value = value.replaceAll("^(0+)", "").toUpperCase();
    // 初始化map,将字符数组中的按索引存入map,字符相当于key, value相当于十进制的值
    int LEN = NUMBER.length;
    Map<Character, Integer> numberMap = new HashMap<>(LEN);
    for (int i = 0; i < LEN; i++) {
      numberMap.put(NUMBER[i], i);
    }
    // 数值转为字符数组
    char[] sh = value.toCharArray();
    int len = sh.length;
    // 位数
    int n = 0;
    long sum = 0;
    for (char item : sh) {
      // 从后位往前加
      // 根据公式 S = x ** y * z (x代表进制,y代表位数,z代表该位上的值)
      sum += (numberMap.get(item)) * Math.pow(numberBase, len - (n++) - 1);
    }
    return sum;
  }

10进制转各进制

将10进制转换成各进制就是一个连续除以各进制的过程
把要转换的数,除以各进制,得到余数 ,商取整数,然后将商继续除以各进制,直到商为0。最后将所有余数倒序排列,得到的数就是转换结果。

例如10进制转8进制:
十进制 20

第一轮:
       余数 : 20 % 8 = 4 --->  存入栈
 	   商:   20 / 8 ≈ 2
第二轮:
       余数 :2 % 8 = 2 --->  存入栈
 	   商: 	2 / 8 ≈ 0
 最后就可以得到 20 的 8 进制数  为 24

这里用了栈的先进后出的特性,最后再循环将栈顶弹出

 public static String toOtherBase(long value, int base) { //base为目标进制
    StringBuilder str = new StringBuilder();  // 进制大于十 会有字母,所以用字符串
    Stack<Character> stack = new Stack<>();
    while (value != 0) { // 一直除以目标进制,直到value为0
      stack.push(NUMBER[(int) (value % base)]); // 求余数
      value /= base; // 求商
    }
    while (!stack.isEmpty()) {  // 弹出栈顶元素。
      str.append(stack.pop());
    }
    return str.toString();
  }
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/aiyaiyayayaya/article/details/106202076
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢