在Java中从一个基数转换为另一个基数

时间:2013-03-31 22:02:04

标签: java

现在,我正在尝试找到一种方法,在Java中将数字从一个基数转换为另一个基数,给出一个数字,数字所在的基数,以及转换为的基数。

public static void BaseConversion(String number, int base1, int base2){
    //convert the number from one base to another
}

我找到了JavaScript的解决方案,我想知道是否有可能在Java中做类似的事情:

function convertFromBaseToBase(str, fromBase, toBase){
    var num = parseInt(str, fromBase); //convert from one base to another
    return num.toString(toBase);
}

10 个答案:

答案 0 :(得分:50)

你可以做到

return Integer.toString(Integer.parseInt(number, base1), base2);

使用您的函数签名,在Java中:

public String convertFromBaseToBase(String str, int fromBase, int toBase) {
    return Integer.toString(Integer.parseInt(str, fromBase), toBase);
}

答案 1 :(得分:8)

public class BaseToBaseConv {

static String baseToBase(String num, int base1, int base2) {
    int no = convFrmBaseToDeci(num, base1);
    return convFrmDecToBase(no, base2);
}

static String convFrmDecToBase(int num, int base) {

    String res = "";
    int rem;
    // Convert input number is given base by repeatedly
    // dividing it by base and taking remainder
    while (num > 0) {
        rem = num % base;
        if (base == 16) {
            if (rem == 10)
                res += 'A';
            else if (rem == 11)
                res += 'B';
            else if (rem == 12)
                res += 'C';
            else if (rem == 13)
                res += 'D';
            else if (rem == 14)
                res += 'E';
            else if (rem == 15)
                res += 'F';
            else
                res += rem;
        } else
            res += rem;

        num /= base;
    }
    // Reverse the result
    return new StringBuffer(res).reverse().toString();
}

static int convFrmBaseToDeci(String num, int base) {

    if (base < 2 || (base > 10 && base != 16))
        return -1;

    int val = 0;
    int power = 1;

    for (int i = num.length() - 1; i >= 0; i--) {
        int digit = digitToVal(num.charAt(i));

        if (digit < 0 || digit >= base)
            return -1;

        // Decimal equivalent is str[len-1]*1 +
        // str[len-1]*base + str[len-1]*(base^2) + ...
        val += digit * power;
        power = power * base;
    }

    return val;
}

static int digitToVal(char c) {
    if (c >= '0' && c <= '9')
        return (int) c - '0';
    else
        return (int) c - 'A' + 10;
}

public static void main(String [] args) {
    System.out.println(baseToBase("12345", 10, 2));
    System.out.println(baseToBase("11000000111001", 2, 10));
    System.out.println(baseToBase("ABC11", 16, 2));
    System.out.println(baseToBase("10101011110000010001", 2, 16));
    System.out.println(baseToBase("12322", 8, 16));
}
}

答案 2 :(得分:4)

我相信这会奏效:

long x = 10;
int baseToConvertTo = 9;
System.out.println(Long.toString(x, baseToConvertTo));

输出:11

答案 3 :(得分:3)

正如其他人所展示的那样,Integer.parseInt()可以为您做到这一点。但是,如果您自己尝试构建转换器,则以下操作只需将数值转换为所需的基数即可。注意,对于基数10以上的基数,你必须考虑alpha字符... I.E. 11-A,12-B等...

public class NumberUtil {

    /**
     * This example is convoluted as in reality it just uses 'toString' to convert the number...
     * However, it displays the logic needed to make the conversion...
     *
     * To convert a number to a new radix, recursively return the remainder of the number
     * divided by the radix for each operation until zero. Then return the concatenated value in reverse.
     *
     * Example convert 9658 to base 2
     *
     * 9658 / 2 = 4829 R 0
     * 4829 / 2 = 2414 R 1
     * 2414 / 2 = 1207 R 0
     * 1207 / 2 =  603 R 1
     * 603  / 2 =  301 R 1
     * 301  / 2 =  150 R 1
     * 150  / 2 =   75 R 0
     * 75   / 2 =   37 R 1
     * 37   / 2 =   18 R 1
     * 18   / 2 =    9 R 0
     * 9    / 2 =    4 R 1
     * 4    / 2 =    2 R 0
     * 2    / 2 =    1 R 0
     * 1    / 2 =    0 R 1
     *
     * Answer :: 10010110111010
     *
     * @param number :: Integer number to convert.
     * @param radix  :: Radix to convert to.
     * @return :: BigInteger of the number converted to the desired radix.
     */
    static BigInteger convertBase( int number, int radix ) {

        List<Integer> remainder = new ArrayList<>();

        int count = 0;
        String result = "";
        while( number != 0 ) {
            remainder.add( count, number % radix != 0 ? number % radix : 0 );
            number /= radix;
            try {
                result += remainder.get( count );
            } catch( NumberFormatException e ) {
                e.printStackTrace();
            }
        }
        return new BigInteger( new StringBuffer( result ).reverse().toString() );
    }

    public static void main( String[] args ) {

        System.out.println( convertBase( 9658, 2 ) );

    }
}

答案 4 :(得分:2)

测试:

class Test1 {
    public static void main(String[] args) {
        String s1 = "10";
        int n1 = Integer.parseInt(s1, 8);
        System.out.println(s1 + " is " + n1 + " in base10");
        String s2 = Integer.toString(n1, 2);
        System.out.println(n1 + " is " + s2 + " in base2");
    }
}

给出:

C:\Temp>java Test1
10 is 8 in base10
8 is 1000 in base2

使用Integer.parseIntInteger.toString

答案 5 :(得分:1)

如果您可以确定相关数字分别在Integer.parseIntLong.parseLong范围内,则intlong的双参数版本会执行此操作。如果您无法保证这一点,请使用java.math.BigInteger

BigInteger bi = new BigInteger(number, base1);
return bi.toString(base2);

这可以处理任意大的整数,例如

System.out.println(
  new BigInteger("12345678901234567890123456789", 10).toString(16));
// prints 27e41b3246bec9b16e398115 - too big to represent as a long

答案 6 :(得分:0)

由于您在js代码中提到int,因此Integer课程中有两种方法可供您查看:

static int  parseInt(String s, int radix) 
          Parses the string argument as a signed integer in the radix specified by the second argument.

static String toString(int i, int radix) 
          Returns a string representation of the first argument in the radix specified by the second argument.

答案 7 :(得分:0)

使用此代码

import java.util.Scanner; // import scanner class

public class BaseConverting {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in); //creating object from Scanner class
        String ans;

        System.out.println("Enter the decimal value need to convert !");
        int decimal_value = input.nextInt();    //getting decimal value from user

        System.out.println("Select base \n Binary - b ;\n Octal- o ;\n HexaDecimal -h ;");
        String choice = input.next();           //getting user needs Base type

        switch (choice) {
            case "b":
                ans = Integer.toString(decimal_value, 2);
                System.out.println("Binary value of " + decimal_value + " = " + ans);
                break;

            case "o":
                ans = Integer.toString(decimal_value, 8);
                System.out.println("Octal value of " + decimal_value + " = " + ans);
                break;

            case "h":
                ans = Integer.toString(decimal_value, 16);
                System.out.println("Hexa Decimal value of " + decimal_value + " = " + ans);
                break;
        }

    }

}

答案 8 :(得分:0)

这个怎么样?

public static void main(String[] args) {

    System.out.println(toDecimalBase("11111111", 2));
    System.out.println(toDecimalBase("Ff", 16));
    System.out.println(toDecimalBase("377", 8));
    System.out.println(toDecimalBase("255", 10));
}

private static int toDecimalBase(String number, int base) {

    int lenght = number.length();
    int result = 0;

    for (int i = 0; i < lenght; i++) {

        // get char in a reverse order from the array
        int character = number.charAt(lenght - i - 1);

        // convert range [A-F] to range of [0-6]
        if (character >= 'A' && character <= 'F') {
            character = character - 'A' + 10;
        } 
        else if (character >= 'a' && character <= 'f') {
            character = character - 'a' + 10;
        }
        // Unicode to int
        else {
            character = Character.getNumericValue(character);
        }
        result += (Math.pow(base, i)) * character;
    }

    return result;
}

答案 9 :(得分:0)

BaseEncoder

BaseEncoder是为这个问题写的。

注释

  • 支持 base 2 base 3263
  • 未针对速度进行优化
  • Base 64是非标准的

输出

    baseConversion("10011100", 2,  16) = "9C"
    baseConversion("9c",      16,   2) = "10011100"
    baseConversion("609643",  10,  64) = "2Krh"
    baseConversion("33773377",10, 100) = "bÈbÈ"
    baseConversion("18018018",10,1000) = "NNN"

使用

    sout("(\"10011100\", 2,  16)=" + baseConversion("10011100", 2, 16));
    sout("(\"9c\",      16,   2)=" + baseConversion("9c", 16, 2));
    sout("(\"609643\",  10,  64)=" + baseConversion("609643", 10, 64));
    sout("(\"33773377\",10, 100)=" + baseConversion("33773377", 10, 100));
    sout("(\"18018018\",10,1000)=" + baseConversion("18018018", 10, 1000));

来源

/*
 * Licensced for commercial or non-commercial use, modification and 
 * redistribution provided the source code retain this license header and 
 * attribution.  Written to answer to Stack Overflow question 15735079.  See
 * https://stackoverflow.com/questions/15735079/
 * to see the original questions and ( if this code has been modified ) to see 
 * the original source code.  This license does not supercede any licencing
 * requirements set forth by StackOverflow.  In the event of a disagreement
 * between this license and the terms of use set forth by StackOverflow, the
 * terms of use and/or license set forth by StackOverflow shall be considered 
 * the governing terms and license.
 */
package org.myteam.util;

import java.math.BigInteger;

/**
 * conversion routines to support
 * <pre>
 * BaseEncoder.baseConversion("94d6b", 16, 2));
 * </pre> allowing conversions between numbering systems of base 2 to base 3263
 * inclusive, with the following caveats:<ul>
 * <li> WARNING: BASE64 numbers created or parsed with this encoder are not
 * compatible with a standard base 64 encoder, and </li>
 * <li> WARNING: this class does not currently support unicode, or if it does
 * that's only by accident and it most likely does not support characters that
 * require more than one codepoint.</li>
 * </ul>
 * . to convert between two non-standard numbering systems, use two BaseEncoder
 * objects e.g.
 * <pre>
 *
 *      String numberBase64 = "1X3dt+4N";
 *      String numberBase16 = new BaseEncoder(16).fromBase10(new BaseEncoder(
 *          "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/")
 *          .toBase10(numberBase64));
 *
 * </pre>
 *
 * @see https://stackoverflow.com/questions/15735079/
 */
public class BaseEncoder {

    public static void main(String[] args) {
        sout("(\"10011100\", 2,  16)=" + baseConversion("10011100", 2, 16));
        sout("(\"9c\",      16,   2)=" + baseConversion("9c", 16, 2));
        sout("(\"609643\",  10,  64)=" + baseConversion("609643", 10, 64));
        sout("(\"33773377\",10, 100)=" + baseConversion("33773377", 10, 100));
        sout("(\"18018018\",10,1000)=" + baseConversion("18018018", 10, 1000));
        // test();
    }

    private static void sout(String output) {
        System.out.println("\tbaseConversion" 
                + output.replace("=", " = \"") + "\"");
    }

    /**
     * this is the method that satisfies the criteria set forth by the original
     * question at https://stackoverflow.com/questions/15735079/ .
     *
     * @param fromNumber
     * @param fromBase
     * @param toBase
     * @return
     */
    public static String baseConversion(
            String fromNumber, int fromBase, int toBase) {
        final BigInteger numberBase10 = fromBase == 10
                ? new BigInteger(fromNumber)
                : parseBigInteger(fromNumber, fromBase);
        // System.out.println("org.myteam.util.baseConversion():"
        //          + " numberBase10 = " + numberBase10);
        return toBase == 10 ? numberBase10.toString()
                : toString(numberBase10, toBase);
    }

    /**
     * Simple test to validate conversion functions. Should be converted to
     * support whatever unit tests or automated test suite your organization
     * employs. No return value.
     *
     * @throws IllegalStateException if any test fails, and aborts all tests.
     */
    public static void test() throws IllegalStateException {
        final int level1 = 100;
        final int level2 = 525;
        final int level3 = 1000;
        final int maxlvl = 3263;
        for (int radix = 2; radix < maxlvl;) {
            test(radix);
            radix += (radix < level1) ? 1
                    : (radix < level2) ? 17
                            : (radix < level3) ? 43
                                    : 139;
        }
        test(3263);
        System.out.println("taurus.BaseEncoder.test(): all tests passed.");
    }

    private static void test(int radix) throws IllegalStateException {
        final BigInteger level1 = BigInteger.valueOf(radix);
        final BigInteger level2 = level1.multiply(level1);
        final BigInteger level3 = level2.multiply(level1);
        final BigInteger maxlvl = level3.multiply(level1);
        final BigInteger increment1 = BigInteger.ONE;
        final BigInteger increment2 = level1.add(BigInteger.ONE);
        final BigInteger increment3 = level2
                .add(BigInteger.ONE).add(BigInteger.ONE).add(BigInteger.ONE);
        final BigInteger increment4 = level3.add(BigInteger.valueOf(17));
        final int exitLvl = 5;
        int prevLvl = 1;
        BigInteger iTest = BigInteger.ZERO;
        while (true) {
            Throwable err = null;
            String radixEncoded = "(conversion to base " + radix + " failed)";
            String backToBase10 = "(conversion back to base 10 failed)";
            try {
                radixEncoded = baseConversion("" + iTest, 10, radix);
                backToBase10 = baseConversion(radixEncoded, radix, 10);
            } catch (Throwable ex) {
                err = ex;
            }
            if (err != null || !backToBase10.equals("" + iTest)) {
                System.out.println("FAIL: "
                        + iTest + " base " + radix + " = " + radixEncoded);
                System.out.println("FAIL: "
                        + radixEncoded + " base 10 = " + backToBase10
                        + " (should be " + iTest + ")");
                throw new IllegalStateException("Test failed. base 10 '" + iTest
                        + "' conversion to/from base" + radix + ".", err);
            }
            int lvl = (prevLvl == 1 && iTest.compareTo(level1) >= 0) ? 2
                    : (prevLvl == 2 && iTest.compareTo(level2) >= 0) ? 3
                    : (prevLvl == 3 && iTest.compareTo(level3) >= 0) ? 4
                    : (prevLvl == 4 && iTest.compareTo(maxlvl) >= 0) ? exitLvl
                    : prevLvl;
            final BigInteger increment
                    = (lvl == 1) ? increment1
                            : (lvl == 2) ? increment2
                                    : (lvl == 3) ? increment3
                                            : (lvl == 4) ? increment4
                                                    : BigInteger.ZERO;
            iTest = iTest.add(increment);
            if (prevLvl != lvl) {
                if (lvl == exitLvl && (radix % 56 == 0 || radix > 2700)) {
                    System.out.println("test():" + " radix " + radix
                            + " level " + prevLvl + " test passed.");
                }
            }
            if (lvl == exitLvl) {
                break;
            }
            prevLvl = lvl;
        }
    }

    /**
     * <pre>
     * String tenAsOctal = toString(BigInteger.TEN, 8); // returns "12"
     * </pre>.
     *
     * @param numberBase10
     * @param radix
     * @return
     */
    public static String toString(BigInteger numberBase10, int radix) {
        return new BaseEncoder(radix).fromBase10(numberBase10);
    }

    /**
     * <pre>
     * String tenAsOctal = toString(BigInteger.TEN, "01234567"); // returns "12"
     * </pre>.
     *
     * @param numberBase10
     * @param digits
     * @return
     */
    public static String toString(BigInteger numberBase10, String digits) {
        return new BaseEncoder(digits).fromBase10(numberBase10);
    }

    /**
     * <pre>
     * String tenAsOctal = "12"; // ("1" x 8^1) + ("2" x 8^0) = 10
     * String tenAsDecimal = parseBigInteger(tenAsOctal, 8);
     * System.out.println(tenAsDecimal); // "10"
     * </pre>.
     *
     * @param numberEncoded
     * @param radix
     * @return
     */
    public static BigInteger parseBigInteger(String numberEncoded, int radix) {
        return new BaseEncoder(radix).toBase10(numberEncoded);
    }

    /**
     * <pre>
     * String tenAsOctal = "12"; // ("1" x 8^1) + ("2" x 8^0) = 10
     * String tenAsDecimal = parseBigInteger(tenAsOctal, "01234567");
     * System.out.println(tenAsDecimal); // "10"
     * </pre>.
     *
     * @param numberEncoded
     * @param digits
     * @return
     */
    public static BigInteger parseBigInteger(
            String numberEncoded, String digits) {
        return new BaseEncoder(digits).toBase10(numberEncoded);
    }

    /**
     * <pre>
     * String tenAsOctal = "12"; // ("1" x 8^1) + ("2" x 8^0) = 10
     * int tenAsDecimal = parseInt(tenAsOctal, 8);
     * System.out.println(tenAsDecimal); // 10
     * </pre>.
     *
     * @param numberEncoded
     * @param radix
     * @return
     */
    public static int parseInt(String numberEncoded, int radix) {
        return new BaseEncoder(radix).toBase10(numberEncoded).intValueExact();
    }

    /**
     * <pre>
     * String tenAsOctal = "12"; // ("1" x 8^1) + ("2" x 8^0) = 10
     * int tenAsDecimal = parseInt(tenAsOctal, "01234567");
     * System.out.println(tenAsDecimal); // 10
     * </pre>.
     *
     * @param numberEncoded
     * @param digits
     * @return
     */
    public static int parseInt(String numberEncoded, String digits) {
        return new BaseEncoder(digits).toBase10(numberEncoded).intValueExact();
    }

    /**
     * <pre>
     * String tenAsOctal = "12"; // ("1" x 8^1) + ("2" x 8^0) = 10
     * long tenAsDecimal = parseLong(tenAsOctal, 8);
     * System.out.prlongln(tenAsDecimal); // 10
     * </pre>.
     *
     * @param numberEncoded
     * @param radix
     * @return
     */
    public static long parseLong(String numberEncoded, int radix) {
        return new BaseEncoder(radix).toBase10(numberEncoded).longValueExact();
    }

    /**
     * <pre>
     * String tenAsOctal = "12"; // ("1" x 8^1) + ("2" x 8^0) = 10
     * long tenAsDecimal = parseLong(tenAsOctal, "01234567");
     * System.out.prlongln(tenAsDecimal); // 10
     * </pre>.
     *
     * @param numberEncoded
     * @param digits
     * @return
     */
    public static long parseLong(String numberEncoded, String digits) {
        return new BaseEncoder(digits).toBase10(numberEncoded).longValueExact();
    }

    /**
     * each character in this string represents one digit in the base-X
     * numbering system supported by this instance, where X = the length of the
     * string. e.g.
     * <pre>
     *     base  2 (binary)     digits = "01"
     *     base  8 (octal)      digits = "01234567"
     *     base 10 (decimal)    digits = "0123456789"
     *     base 16 (hexdecimal) digits = "0123456789ABCDEF"
     * </pre> digits follow this pattern until base 64. a somewhat arbitrary
     * character system is utilized to support base 65 to base 3263.
     */
    private final String digits;

    /**
     * specify a numbering system between base 2 and base 64 inclusive
     * <pre>
     * String fiveAsBinary = new BaseEncoder(2).fromBase10(5);
     * System.out.println(fiveAsBinary); // "101"
     * </pre> to use a numbering system with more than 64 digits, or to use your
     * own custom digits, use
     * <pre>
     * new BaseEncoder(String)
     * </pre>.
     *
     * @param radix
     */
    public BaseEncoder(int radix) {
        String digitsTemp = getDefaultDigitsForBase(radix);
        digits = digitsTemp;
    }

    /**
     * specify digits to use for your numbering system for example base 16 could
     * be represented as
     * <pre>
     *      new BaseEncoder("0123456789ABCDEF")
     * </pre> <br>
     * and base 64 could be represented as
     * <pre>
     *      new BaseEncoder("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     *              + "abcdefgjijklmnopqrstuvwxyz+/")
     * </pre>.
     *
     * @param digits
     */
    public BaseEncoder(String digits) {
        if (digits.length() < 2) {
            final String errorMessage = "Supported bases include 2 and above."
                    + " " + "Please provide at least two characters"
                    + " " + "e.g. new BaseEncoder(\"01\") // binary or base 2";
            throw new IllegalArgumentException(errorMessage);
        }
        this.digits = digits;
    }

    /**
     * convert a number from a non-standard numbering format to base 10
     * (BigInteger).
     *
     * @param numberEncoded
     * @return
     */
    public BigInteger toBase10(final String numberEncoded) {
        final int radix = digits.length();
        final BigInteger magnitude = BigInteger.valueOf(radix);
        final char[] chars = numberEncoded.toCharArray();
        BigInteger numberBase10 = BigInteger.ZERO;
        for (int i = 0; i < chars.length; i++) {
            numberBase10 = numberBase10.multiply(magnitude);
            final char digitEncoded = chars[i];
            final int indexOf = digits.indexOf(digitEncoded);
            final int digitValue;
            if (indexOf == -1) {
                digitValue = digits.toLowerCase().indexOf(
                        Character.toLowerCase(digitEncoded));
            } else {
                digitValue = indexOf;
            }
            if (digitValue == -1) {
                final String errorMessage = "Digit '" + digitEncoded + "'"
                        + " " + "from base " + radix + " number"
                        + " " + "'" + numberEncoded + "' not found in"
                        + " " + "base " + radix + " digits '" + digits + "'.";
                throw new IllegalArgumentException(errorMessage);
            }
            numberBase10 = numberBase10.add(BigInteger.valueOf(digitValue));
        }
        return numberBase10;
    }

    /**
     * convert a number from a non-standard numbering format to base 10
     * (BigInteger).
     *
     * @param numberBase10
     * @return
     */
    public String fromBase10(long numberBase10) {
        return fromBase10(BigInteger.valueOf(numberBase10));
    }

    /**
     * convert a number from a non-standard numbering format to base 10
     * (BigInteger).
     *
     * @param numberBase10
     * @return
     */
    public String fromBase10(BigInteger numberBase10) {
        final StringBuilder encodedNumber = new StringBuilder("");
        final int radix = digits.length();
        final BigInteger magnitude = BigInteger.valueOf(radix);
        while (numberBase10.compareTo(BigInteger.ZERO) > 0) {
            final BigInteger[] divideAndRemainder = numberBase10
                    .divideAndRemainder(magnitude);
            final BigInteger quotient = divideAndRemainder[0];
            final BigInteger remainder = divideAndRemainder[1];
            encodedNumber.insert(0, digits.charAt(remainder.intValueExact()));
            numberBase10 = quotient;
        }
        return encodedNumber.toString();
    }

    public static String getDefaultDigitsForBase(int radix) throws IllegalArgumentException {
        if (radix < 2) {
            final String errorMessage = "Supported bases include 2 and above."
                    + " " + "Not really sure how to represent"
                    + " " + "base " + radix + " numbers.";
            throw new IllegalArgumentException(errorMessage);
        } else if (radix <= 64) {
            return ("0123456789ABCDEFGHIJKLMNOPQRSTUV" // base 32 ends at V
                    + "WXYZabcdefghijklmnopqrstuvwxyz+/").substring(0, radix);
        }
        int charCount = 0;
        final StringBuilder s = new StringBuilder();
        for (int i = Character.MIN_VALUE; i < Character.MAX_VALUE; i++) {
            switch (Character.getType(i)) {
                case Character.CONNECTOR_PUNCTUATION:
                case Character.CURRENCY_SYMBOL:
                case Character.FINAL_QUOTE_PUNCTUATION:
                case Character.INITIAL_QUOTE_PUNCTUATION:
                case Character.LETTER_NUMBER:
                case Character.LINE_SEPARATOR:
                case Character.LOWERCASE_LETTER:
                case Character.MATH_SYMBOL:
                case Character.UPPERCASE_LETTER:
                    s.append((char) i);
                    if (++charCount >= radix) {
                        return s.toString();
                    }
                    break;
            }
        }
        throw new IllegalArgumentException("Radix '" + radix + "' exceeds maximum '" + charCount + "'");
    }

}