If I have a decimal number, how do I convert it to base 36 in Java?
Maybe I'm late to the party, but this is the solution I was using for getting Calc/Excel cell names by their index:
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);
}
}
Results:
A
C
Z
AA
AZ
BA
TA
Basically the solution accepts any custom radix. The idea was commandeered from here.
The following can work for any base, not just 36. Simply replace the String contents of code
.
Encode:
int num = 586403532;
String code = "0123456789abcdefghijklmnopqrstuvwxyz";
String text = "";
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();
}
Decode:
String text = "0vn4p9";
String code = "0123456789abcdefghijklmnopqrstuvwxyz";
int num = 0;
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);
}
First you have to convert your number it into the internal number format of Java (which happens to be 2-based, but this does not really matter here), for example by Integer.parseInt()
(if your number is an integer less than 2^31). Then you can convert it from int
to the desired output format. The method Integer.toString(i, 36)
does this by using 0123456789abcdefghijklmnopqrstuvwxyz
as digits (the decimal digits 0-9 and lower case english letters in alphabetic order). If you want some other digits, you can either convert the result by replacing the "digits" (for example toUpperCase
), or do the conversion yourself - it is no magic, simply a loop of taking the remainder modulo 36 and dividing by 36 (with a lookup of the right digit).
If your number is longer than what int offers you may want to use long
(with Long
) or BigInteger
instead, they have similar radix-converters.
If your number has "digits after the point", it is a bit more difficult, as most (finite) base-X-numbers are not exactly representable as (finite) base-Y-numbers if (a power of) Y is not a multiple of X.
Not sure if the above answers did help but noting 'decimal' and 'to base36' I assume you want to convert a numeric value to base36. And as long as the Long
value of the raw figure is within (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
I got this code from this website in JavaScript, and this is my version in 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;
}
This supports negative numbers and custom bases.
Decimal Addon:
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);
}