java任意进制转换

1 篇文章 0 订阅

摘要

我们日常常用的是十进制。

计算机是基于二进制的,计算机常用的还有十六进制、八进制。

本文主要介绍如何实现十进制和任意进制间转换。

计算思想

如果用:【0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ你我】分别代表数字。则A代表36,你代表62,我代表63.

1、任意进制转10进制。比如64进制:A你我,可分解为

A你我 = 我*1+你*64+A*64*64=63*1+62*64+36*64*64=151487;

2、10进制转任意进制。还是151487。

y=m*r^x = m0*1+m1*64+m2*64^2+m3*64*3+...mi*64^i=151487,我们需要计算出所有次幂x及对应的乘数m.

我们先算用算出它的最高次幂,x=log(151487)/log(64),取整为2,即最大次幂为2。

计算出对应乘数m2=151487/64^2,取整为36。

计算余数=151487对36*64^2取余数。

对余数分别再用上面的方法计算,即可获得所有的乘数和次幂。分别是:2次幂-36,1次幂-62,0次幂-63。 即结果为:36,62,63,对应字符串为:A你我。

注意:中间如果有某些次幂不存在,也需要补0作为乘数。如:5*64^5+3*64^1=5*64^5+0*64^4+0*64^3+0*64^2+3*64^1+0*64^0=500030

代码实现

任意进制转10进制:

    /**
     * 任意进制转换成十进制
     * @param num 要转换的任意进制数字
     * @param radix 当前要转换的数字进制
     * @param dict 目标进制数值和字符对应关系,如:0-0 a-10 z-35
     * @return
     */
    public static int radixConvert10(String num, int radix, Map<String, Integer> dict){
        String[] nums = num.split("");
        int result=0;
        for(int i=0; i<nums.length; i++){
            // y=m*r^x = m0*r^0+m1*r^1+m2*r^2+...+mi*r^i+...
            // 从后往前累加
            String mi_str = nums[nums.length-i-1];
            int mi=dict.get(mi_str);
            result += mi*Math.pow(radix,i);
        }
        return result;
    }

    /**
     * 任意进制转换成十进制
     * @param num 要转换的10进制数字
     * @param radix 目标进制
     * @param numberOrder 目标进制代替数字的字符串顺序,如:0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
     * @return
     */
    public static int radixConvert10(String num, int radix, String numberOrder){
        String[] split = numberOrder.split("");
        Map<String, Integer> dict = new HashMap<>();
        //做字符串和数字的对应关系
        for(int i=0; i<split.length; i++){
            dict.put(split[i],i);
        }
        return radixConvert10(num, radix, dict);
    }

十进制转任意进制:

    /**
     * 十进制转换成任意进制
     * @param num 要转换的10进制数字
     * @param radix 目标进制
     * @param dict 目标进制数值和字符对应关系,如:0-0 10-a 35-z
     * @return
     */
    public static String radixConvert(int num, int radix, Map<Integer, String> dict){
        if(num<radix){
            //个位数,直接获取
            return dict.get(num);
        }
        int temp = num;
        int prex=0;
        List<Integer> ms = new ArrayList<>();
        while (temp>0){
            // 获取最大的幂, 如m*r^x
            int x = (int)(Math.log(temp) / Math.log(radix));
            // 获取该幂的乘数
            int m = (int)(temp / Math.pow(radix, x));
            // 如果前一次幂比后一次幂大超过1
            while (prex>x+1){
                ms.add(0);
                prex--;
            }
            prex=x;
            ms.add(m);
            // 取余,再循环进行下一次幂运算
            temp = temp % (m * (int)Math.pow(radix, (x)));
        }
        while (prex>0){
            ms.add(0);
            prex--;
        }
        StringBuilder sb = new StringBuilder();
        for(Integer m:ms){
            sb.append(dict.get(m));
        }
        return sb.toString();
    }

    /**
     * 十进制转换成任意进制
     * @param num 要转换的10进制数字
     * @param radix 目标进制
     * @param numberOrder 目标进制代替数字的字符串顺序,如:0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
     * @return
     */
    public static String radixConvert(int num, int radix, String numberOrder){
        String[] split = numberOrder.split("");
        Map<Integer, String> dict = new HashMap<>();
        //做字符串和数字的对应关系
        for(int i=0; i<split.length; i++){
            dict.put(i,split[i]);
        }
        return radixConvert(num, radix, dict);
    }

测试:

    public static void main(String[] args) {
        String numberOrder = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ你我";
        String num="A你我";
        int n = radixConvert10(num, 64, numberOrder);
        System.out.println(num+"(64进制)="+n+"(10进制)");
        String s = radixConvert(n, 64, numberOrder);
        System.out.println(n+"(10进制)="+s+"(64进制)");
    }

运行结果:

A你我(64进制)=151487(10进制)
151487(10进制)=A你我(64进制)

暂不支持负数,负数可先去掉符号转成正数,然后再计算。任意进制转换的作用和意义,这里不作解释。

***********************************************************************************************
author:蓝何忠
email:lanhezhong@163.com
***********************************************************************************************

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值