【问题标题】:In Java how do you convert a decimal number to base 36?在 Java 中,如何将十进制数转换为基数 36?
【发布时间】:2011-02-20 23:39:49
【问题描述】:

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

【问题讨论】:

  • A. Base 36 从 0 一直到 Z。想象一下它就像一个硬核十六进制。
  • @SOE,在基数 36 中 9 + 1 如何以图形/可打印方式表示 没有区别。任何基数中 9 之后的值都是二进制 1001 + 1 = 1010. 在十六进制表示法中,此值由可打印字符“A”表示,但也可以是“%”或“/”,甚至 [gulp] 空格字符。
  • Base 42 会更合适...
  • 26 个字母 + 10 个数字 = 36

标签: java math decimal


【解决方案1】:

给定一个号码i,使用Integer.toString(i, 36)

【讨论】:

  • 或者使用常量Integer.toString(i, Character.MAX_RADIX) 我不认为它会很快改变。 ;)
  • 但它可能改变(因为它的值没有指定),然后答案不会是基数 36,所以最好坚持使用普通的旧 Integer.toString(i, 36)
  • 查看 base_36 维基百科网站上的 java 代码示例:en.wikipedia.org/wiki/Base_36
【解决方案2】:

查看 Integer.toString 的文档

http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString(int,%20int)

toString

public static String toString(int i, int radix)
....
The following ASCII characters are used as digits:

   0123456789abcdefghijklmnopqrstuvwxyz

radix 是什么? Base 36 你很幸运(这是有道理的)
http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#MAX_RADIX

public static final int     MAX_RADIX   36

【讨论】:

    【解决方案3】:

    以下内容适用于任何基数,而不仅仅是 36。只需替换 code 的字符串内容。

    编码:

    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);
    }
    

    【讨论】:

    • code 的更好名称可能是 charset
    • 很抱歉,编码部分完全是错误的:log(0) 未定义,将失败。 log(1) 产生 0 并将完全跳过循环。每个 num = code.length^x (e.g 36^1, 36^2, 36^n) 将导致 "0"
    • 输入 1 作为值时失败(解码 1 --> 0)
    【解决方案4】:

    首先,您必须将您的数字转换为 Java 的内部数字格式(它恰好是基于 2 的,但这在这里并不重要),例如通过Integer.parseInt()(如果您的数字是一个小于整数大于 2^31)。然后您可以将其从int 转换为所需的输出格式。 Integer.toString(i, 36) 方法通过使用 0123456789abcdefghijklmnopqrstuvwxyz 作为数字(十进制数字 0-9 和按字母顺序排列的小写英文字母)来实现此目的。如果您想要一些其他数字,您可以通过替换“数字”(例如toUpperCase)来转换结果,或者自己进行转换 - 这并不神奇,只是一个取余数模 36 并除以的循环36(查找正确的数字)。

    如果您的号码比 int 提供的号码长,您可能希望使用 long(与 Long)或 BigInteger 代替,它们具有相似的基数转换器。

    如果您的数字有“点后面的数字”,那就有点困难了,因为如果(的幂)大多数(有限)base-X-numbers 不能完全表示为(finite)base-Y-numbers Y 不是 X 的倍数。

    【讨论】:

      【解决方案5】:

      此代码有效:

      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;
          }
      
      
      }
      

      【讨论】:

      • 尝试 text="ZZ" 失败。为什么? ZZ 小于最大 int。
      【解决方案6】:

      如果您不想使用 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

      【讨论】:

        【解决方案7】:

        也许我迟到了,但这是我用来通过索引获取 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
        

        基本上,该解决方案接受任何自定义基数。这个想法是从here 征用的。

        【讨论】:

        • 很好的答案,谢谢...现在,您如何从 base 倒退到 int ? :)
        【解决方案8】:

        不确定上述答案是否有帮助,但请注意“十进制”和“到 base36”我假设您想将数值转换为 base36。并且只要原始图形的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);
        

        输出:39p5pkj5i

        【讨论】:

          【解决方案9】:

          这是一种将基数 10 转换为任何给定基数的方法。

           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;
           }
          

          【讨论】:

            【解决方案10】:

            我从 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
            • 好点,因为 java 会像 Math.floor 一样截断整数。改变答案。 :)
            【解决方案11】:

            这对你有帮助。正在对1679615以下的4位字母数字字符串和十进制数字进行操作。您可以相应地修改代码。

            char[] alpaNum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
                 String currentSeries = "";
                int num = 481261;
                    String result = "";
                    String baseConversionStr = "";
                    boolean flag = true;
                    do 
                    {
                        baseConversionStr = Integer.toString(num % 36) + baseConversionStr;
                        String position = "";
                        if(flag)
                        {
                            flag = false;
                            position = baseConversionStr;
                        }
                        else
                        {
                            position = Integer.toString(num % 36);
                        }
                        result += alpaNum[new Integer(position)];    
                        num = num/36;
               }
                    while (num > 0);
                    
                    StringBuffer number = new StringBuffer(result).reverse();
                    
                    String finalString = "";
                    
                    if(number.length()==1)
                    {
                        finalString = "000"+articleNo;
                    }
                    else if(number.length()==2)
                    {
                        finalString = "00"+articleNo;
                    }
                    else if(number.length()==3)
                    {
                        finalString = "0"+articleNo;
                    }
                    
                    currentSeries = finalString;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-10-19
              • 2012-03-09
              • 1970-01-01
              • 2016-01-13
              • 2014-11-22
              相关资源
              最近更新 更多