silicongolem
silicongolem

Reputation: 1

How do I convert an integer command-line argument i to base k with bases up to 16 using the letters A through F for the digits 11-16 , respectively?

Question prompt: Modify Binary to get a program that takes two integer command-line arguments i and k and converts i to base k. Assume that i is an integer in Java’s long data type and that k is an integer between 2 and 16. For bases greater than 10, use the letters A through F to represent the 11th through 16th digits, respectively.

I have managed to convert decimals to base 2-10 successfully, but I can't seem to convert decimals with the inclusion of the characters A through F that represents the 11th to 16th digits, respectively.

I don't want to use any arrays or lists. I understand my switch statement is lacking functionality that would solve my problem, but I'm not sure how to improve it. I'm trying to solve the problem using a switch statement.

In the code, i represents an integer to convert to base k. k represents a base that can be 2-16.

public class BaseConversion
    {
        public static void main(String[] args)
        {
            int i = Integer.parseInt(args[0]);
            int k = Integer.parseInt(args[1]);
            int power = 1;
            while (power <= i/k)
            {
                power *= k;
            }   // Now power is the largest power of k <= i.
            if (k <= 10)
            {
                while (power > 0)
                {
                    int digit = i / power;
                    System.out.print(digit);
                    i -= digit * power;
                    power /= k;
                }
            }
            else if (k > 10)
            {
                switch (k)
                {
                    case 11: System.out.println('A'); break;
                    case 12: System.out.println('B'); break;
                    case 13: System.out.println('C'); break;
                    case 14: System.out.println('D'); break;
                    case 15: System.out.println('E'); break;
                    case 16: System.out.println('F'); break;
                }
            }
        }    
    }

Upvotes: -1

Views: 708

Answers (2)

Nowhere Man
Nowhere Man

Reputation: 19545

There are several issues in the presented code:

  • negative values are ignored
  • digits in the switch statement should be shifted down by 1: 10 -> a, 11 -> b, .. 15 -> f
  • the conversion to the string is missing, the code is printing digits one by one

So, a StringBuilder should be used to accumulate the result. If the input is negative, minus sign should be appended and the sign is inverted, then the digits are calculated using modulo by k and inserted into the result in reverse order.

private static String convert(long n, int k) {
    assert(2 <= k && k <= 16);
    StringBuilder sb = new StringBuilder();
    int p = 0;
    if (n < 0) {
        sb.append('-');
        n *= -1;
        p = 1;
    }
    while (n > 0) {
        int digit = (int) (n % k);
        n /= k;
        if (digit < 10) {
            sb.insert(p, digit);
        } else {
            sb.insert(p, switch(digit) {
                case 10 -> 'a';
                case 11 -> 'b';
                case 12 -> 'c';
                case 13 -> 'd';
                case 14 -> 'e';
                default -> 'f'; // the only remaining option
            });
        }
    }
    return sb.toString();
}

Similarly, the result may be collected into a String instead of StringBuilder. However, such approach is not recommended generally (string concatenation in a loop):

private static String convert(long n, int k) {
    String s = "";
    String sign = "";
    if (n < 0) {
        sign = "-";
        n *= -1;
    }
    while(n > 0) {
        int digit = (int) (n % k);
        n /= k;
        if (digit < 10) {
            s = digit + s;
        } else {
            s = switch(digit) {
                case 10 -> 'a';
                case 11 -> 'b';
                case 12 -> 'c';
                case 13 -> 'd';
                case 14 -> 'e';
                default -> 'f';
            } + s;
        }
    }
    return sign + s;
}

Upvotes: 0

Thomas
Thomas

Reputation: 88707

If you need to convert an integer (which is base 10) to any other base using a single switch statement you can use something like this:

int i = //take from CLI
int k = //take from CLI

int num = i; //copy so we still have the original input

//we need a string to represent anything but base-10 integers
StringBuilder sb = new StringBuilder();
    
//decompose the input
while( num > 0 ) {
    //extract the last digit
    int digit = num % k;
        
    //map the digit to a character - note: this is NOT k but the digit we extracted from the input
    switch(digit) {            
        case 0,1,2,3,4,5,6,7,8,9:
            sb.append(digit);
            break;
        case 10:
            sb.append("A");
            break;
        case 11:
            sb.append("B");
            break;
        case 12:
            sb.append("C");
            break;
        case 13:
            sb.append("D");
            break;
        case 14:
            sb.append("E");
            break;
        case 15:
            sb.append("F");
            break;
    }

    //reduce the magnitude of the number by 1, i.e. divide by the base
    num /= k;
}

//we extracted the digits from the back so we need to reverse the string for proper left-to-right output
String result = sb.reverse().toString();

This should get you started. Note that it lacks a couple of checks, e.g. if k is in the range [2,16]. It also works with positive numbers so far but negative input could easily be handled by multiplying the number with -1 and adding the sign to the string buffer before the conversion.

Upvotes: 0

Related Questions