Search code examples
javaradix

How to convert from base 10 to base x in java?


What i've done so far:

public static String convert(int base, int target , String number) {
        ArrayList<Integer> numbers= new ArrayList<Integer>();
        for(int i=0;i<number.length();i++) {
            char check=number.charAt(i);
            if(check>='A') {
                numbers.add(Character.getNumericValue(check-'A'+1));
            }
            else {
                numbers.add(Character.getNumericValue(check));
            }
        }
        int answer_10 = 0;
        for(int i=0;i<number.length();i++) {
            answer_10 += Math.pow(numbers.get(number.length()-i-1), base);
        }
        String answer_target ="";
        while(answer_10>0) { // I need help on this part
            for(int i=0;i>0;i++) {
                if(9*Math.pow(target, i)-answer_10<0) {
                    i++;
                }
                else {
                    for(int j=9;j<=0;j--) {
                        if(j*Math.pow(target, i)-answer_10<0) {
                            j-=1;
                            if(j<=10) {
                                answer_target += j*Math.pow(target, i);
                            }
                            else {
                                answer_target += j-'A'+1 ;
                            }
                            answer_10 -= j*Math.pow(target, i);
                            break;
                        }
                    }
                }
            }
        }
        return answer_target;
    }

I need help on the part that converts the number from base 10 to base x as a string. The question limits 2<=x<=20. I couldn't use the built-in converting function by java, as the question asked not to.


Solution

  • Math.pow isn't a good choice for this problem. It is better to use simple multiply /divide cycle.

        public static String convert(int base, int target, String number) {
            if (base < 2 || base > 20)
                throw new IllegalArgumentException("Invalid base "+base);
            if (target < 2 || target > 20)
                throw new IllegalArgumentException("Invalid base "+target);
            int numberStrLen = number.length();
            int numberValue = 0;
            for (int i = 0; i < numberStrLen; i++) {
                char ch = Character.toLowerCase(number.charAt(i));
                int digit;
                if (ch >= '0' && ch <= '9')
                    digit = ch - '0';
                else if (ch >= 'a')
                    digit = ch - 'a' + 10;
                else
                    throw new IllegalArgumentException("Invalid character "+ch+" for base "+base);
                if (digit >= base)
                    throw new IllegalArgumentException("Invalid character "+ch+" for base "+base);
                numberValue = numberValue * base + digit; // <= multiply cycle
            }
            if (numberValue < 0)
                throw new IllegalArgumentException("Signed value: "+numberValue+" for "+number);
            StringBuilder sb = new StringBuilder();
            while (numberValue != 0) {
                int digit = numberValue % target; 
                numberValue = numberValue / target; // <= divide cycle
                char ch;
                if (digit < 10)
                    ch = (char)(digit + '0');
                else
                    ch = (char)(digit - 10 + 'a');
                sb.insert(0, ch);
            }
            if (sb.length() == 0)
                return "0";
            else
                return sb.toString();
        }
    

    And don't forget about int overflow (wraparound ). Maybe use long or even BigInteger?