如何在Java中将十进制数转换为36进制?

55

如果我有一个十进制数,在Java中如何将其转换为36进制?


11
基数36从0到Z覆盖了所有数字和字母,类似于十六进制的高级版。 - Chris Dennett
@SOE,无论在36进制下如何<i>图形/可打印地表示</i>9 + 1都没有区别。在任何进制中,9之后的值都是二进制1001 + 1 = 1010。在十六进制表示法中,这个值由可打印字符'A'表示,但它也可以是'%'、'/'甚至[吞咽]空格字符。 - Pete Wilson
2
基数为42可能更加合适。 - Thorbjørn Ravn Andersen
4
26个字母 + 10个数字 = 36 - enb081
11个回答

90

给定一个数字i,使用Integer.toString(i, 36)函数。


3
或者使用常量Integer.toString(i, Character.MAX_RADIX),我想它不会很快改变。 ;) - Peter Lawrey
18
可能会改变(因为它的值未指定),那么答案就不会是36进制,所以最好还是使用普通的Integer.toString(i, 36)。 - djb
请查看Base_36维基百科网站上的Java代码示例:http://en.wikipedia.org/wiki/Base_36 - edbras

17

14
以下内容适用于任何进制,而不仅限于36进制。只需替换code的String内容即可。
编码:
int num = 586403532;
String code = "0123456789abcdefghijklmnopqrstuvwxyz";
String text = "";
int j = (int)Math.ceil(Math.log(num)/Math.log(code.length()));
for(int i = 0; i < j; i++){
    //i goes to log base code.length() of num (using change of base formula)
    text += code.charAt(num%code.length());
    num /= code.length();
}

解码:

String text = "0vn4p9";
String code = "0123456789abcdefghijklmnopqrstuvwxyz";
int num = 0;
int j = text.length();
for(int i = 0; i < j; i++){
    num += code.indexOf(text.charAt(0))*Math.pow(code.length(), i);
    text = text.substring(1);
}

5
也许将“code”更名为“字符集(charset)”会更合适。 - hcps-tenembasj
2
很抱歉,但编码部分是错误的:log(0)未定义并将失败。 log(1)产生0,并将完全跳过循环。每个num = code.length^x(例如36^1、36^2、36^n)都将导致“0”。 - Oli
当输入1作为值时失败(解码1 --> 0) - Tim Hovius
编码和解码都完全错误。我不知道为什么人们会点赞这个。 - undefined

9
首先,您需要将数字转换为Java的内部数字格式(这个格式是基于2的,但这并不重要),例如通过Integer.parseInt()(如果您的数字是小于2^31的整数)。然后,您可以将其从int转换为所需的输出格式。方法Integer.toString(i, 36)使用0123456789abcdefghijklmnopqrstuvwxyz作为数字(十进制数字0-9和按字母顺序排列的小写英文字母)。如果您想要其他数字,则可以通过替换“digits”(例如toUpperCase)来转换结果,或者自己进行转换 - 这不是魔术,只是一个循环,取余数模36并除以36(查找正确的数字)。
如果您的数字比int提供的更长,您可能需要使用long(使用Long)或BigInteger,它们具有类似的基数转换器。
如果您的数字有“小数点后的数字”,那么它会更加困难,因为大多数(有限的)基于X的数字如果(Y的幂)不是X的倍数,则不能准确表示为(有限的)基于Y的数字。

1
如果您不想使用Integer.toString(Num , base),比如在我的情况下,我需要一个64位长变量,您可以使用以下代码: 在JAVA中使用列表可以方便进行此转换。
long toBeConverted=10000; // example, Initialized by 10000
List<Character> charArray = new ArrayList<Character>();
List<Character> charArrayFinal = new ArrayList<Character>();
int length=10; //Length of the output string
long base = 36;

            while(toBeConverted!=0)
            {
                long rem = toBeConverted%base;
                long quotient = toBeConverted/base;
                if(rem<10)
                    rem+=48;
                else
                    rem+=55;
                charArray.add((char)rem);
                toBeConverted=quotient;
            }
            // make the array in the reverse order
            for(int i=length-1;i>=0;--i){
                if(i>=charArray.size()){
                    charArrayFinal.add((char) 48); // sends 0 to fix the length of the output List
                } else {
                    charArrayFinal.add(charArray.get(i));
                }

            }

例子:

(278197)36=5YNP


1
也许我来晚了,但这是我用于通过索引获取Calc/Excel单元格名称的解决方案:
public static void main(final String[] args) {
    final String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    System.out.println(toCustomBase(0, base));
    System.out.println(toCustomBase(2, base));
    System.out.println(toCustomBase(25, base));
    System.out.println(toCustomBase(26, base));
    System.out.println(toCustomBase(51, base));
    System.out.println(toCustomBase(52, base));
    System.out.println(toCustomBase(520, base));
}

public static String toCustomBase(final int num, final String base) {
    final int baseSize = base.length();
    if(num < baseSize) {
        return String.valueOf(base.charAt(num));
    }
    else {
        return toCustomBase(num / baseSize - 1, base) + base.charAt(num % baseSize);
    }
}

结果:

A
C
Z
AA
AZ
BA
TA

基本上,该解决方案接受任何自定义基数。这个想法被从这里借鉴而来。

好的回答,谢谢...现在,如何从一个基数反向转换为整数? :) - 3xCh1_23

1

不确定上述答案是否有帮助,但是提到“十进制”和“转换为36进制”,我假设您想将数字值转换为36进制。只要原始数字的Long值在(0 - Long.MAX_VALUE)范围内:

String someNumericString = "9223372036854";
Long l = Long.valueOf(someNumericString);
String bases36 = Long.toString(l, 36);

System.out.println("base36 value: "+bases36);

output: 39p5pkj5i


1

This code works:

public class Convert {

    public static void main(String[] args) {
        int num= 2147483647;
        String text="ABCD1";


        System.out.println("num: " + num + "=>" + base10ToBase36(num));
        System.out.println("text: " +text + "=>" + base36ToBase10(text));
    }

    private static String codeBase36 = "0123456789abcdefghijklmnopqrstuvwxyz";

    //"0123456789 abcdefghij klmnopqrst uvwxyz"
    //"0123456789 0123456789 0123456789 012345"


    private static String max36=base10ToBase36(Integer.MAX_VALUE); 

    public static String base10ToBase36(int inNum) {
        if(inNum<0) {
            throw new NumberFormatException("Value  "+inNum +"  to small");
        }
        int num = inNum;
        String text = "";
        int j = (int)Math.ceil(Math.log(num)/Math.log(codeBase36.length()));
        for(int i = 0; i < j; i++){
            text = codeBase36.charAt(num%codeBase36.length())+text;
            num /= codeBase36.length();
        }
        return text;
    }
    public  static int base36ToBase10(String in) {
        String text = in.toLowerCase();
        if(text.compareToIgnoreCase(max36)>0) {
            throw new NumberFormatException("Value  "+text+"  to big");
        }

        if(!text.replaceAll("(\\W)","").equalsIgnoreCase(text)){
            throw new NumberFormatException("Value "+text+" false format");
        }
        int num=0;
        int j = text.length();
        for(int i = 0; i < j; i++){
            num += codeBase36.indexOf(text.charAt(text.length()-1))*Math.pow(codeBase36.length(), i);
            text = text.substring(0,text.length()-1);
        }
        return num;
    }


}

尝试使用文本“ZZ”会失败。为什么?因为“ZZ”小于最大整数。 - 99Valk

0
这里有一种将十进制转换为任意给定进制的方法。
 public char[]  base10Converter(int number, int finalBase) {
    int quo;
    int rem;
    char[] res = new char[1];

    do {
        rem = number % finalBase;
        quo = number / finalBase;
        res = Arrays.copyOf(res, res.length + 1);
        if (rem < 10) {
            //Converting ints using ASCII values
            rem += 48;
            res[res.length - 1] = (char) rem;
        } else {
            //Convert int > 9 to A, B, C..
            rem += 55;
            res[res.length - 1] = (char) rem;
        }
        number /= finalBase;
    } while (quo != 0);


    //Reverse array
    char[] temp = new char[res.length];
    for (int i = res.length - 1, j = 0; i > 0; i--) {
        temp[j++] = res[i];
    }

    return temp;
 }

0

我从this网站上得到了这段JavaScript代码,这是我用Java写的版本:

public static String customBase (int N, String base) {

    int radix = base.length();

    String returns = "";

    int Q = (int) Math.floor(Math.abs(N));
    int R = 0;

    while (Q != 0) {

        R = Q % radix;
        returns = base.charAt(R) + returns;
        Q /= radix; 

    }

    if(N == 0) {
        return String.valueOf(base.toCharArray()[0]);
    }

    return  N < 0 ? "-" + returns : returns;

}

这支持负数和自定义进制。

十进制附加组件:

public static String customBase (double N, String base) {

    String num = (String.valueOf(N));
    String[] split = num.split("\\.");
    if(split[0] == "" || split[1] == "") {
        return "";
    }
    return customBase(Integer.parseInt(split[0]), base)+ "." + customBase(Integer.parseInt(split[1]), base);

}

在整数除法中,(Q-R)/radix 等同于 Q/radix,其中 R = Q % radix - user207421
好的观点,因为Java像Math.floor一样截断整数。更改答案。 :) - nathanfranke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接