J Kupero
J Kupero

Reputation: 1

Having trouble with a Modify.java assignment involving bases using binary

Need help with a certain Java.Binary code process

This is the assignment: Modify Binary.java to get a program Modify.java that takes a second command-line argument K and converts the first argument to base K. Assume the base is between 2 and 16. For bases greater than 10, use the letters A through F to represent the 11th through 16th digits, respectively.

The Binary.java program can be found here: http://introcs.cs.princeton.edu/java/13flow/Binary.java

Does anyone know how to solve this? I've been working on this code for a while but I'm new to coding so I need some help with finishing this project.

This is what I have so far:

public class Modify {
      public static void main(String[] args) {
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        int c = 1;
        int d = 0;
        int e;
        String answer = "";
        boolean term;
        do {
          c *= b;
          if (a >= c) {
            term = true;
            d += 1;
          } else {
            term = false;
          }
        } while (term);
        while (!(a == 0)) {
          int g = 1;
          for (int i = 0; i < d; i++) {
            g *= b;
          }
          d--;
          e = (a / g);
          if (e >= 10) {
            switch (e) {
              case 10:
                answer = answer + "a";
                break;
              case 11:
                answer = answer + "b";
                break;
              case 12:
                answer = answer + "c";
                break;
              case 13:
                answer = answer + "d";
                break;
              case 14:
                answer = answer + "e";
                break;
              case 15:
                answer = answer + "f";
                break;
            }
          } else {
            answer = answer + e;
          }
          a -= g;
        }
        System.out.println(answer);
      }
    }

Upvotes: 0

Views: 215

Answers (1)

user4668606
user4668606

Reputation:

An introduction to numeral systems:
We can write any number x as:

x = a1 * r^0 + a2 * r^1 + a3 * r^2 + ...

where r is the radix (in your problem K). This formula isFor example:

x = 13
r = 2

x = 1 * 2^0 + 0 * 2^1 + 1 * 2^2 + 1 * 2^3

x as binary = 1101

This can be done for any radix.

Getting the list of digits

In order to display the number in any format, we need to get the list of [a1, a2, ...]. To start off, we rewrite the formula from above:

x = a1 * r^0 + a2 * r^1 + a3 * r^2 + ...
x = a1 + r * (a2 + r* (a3 + r * (...)))

Thus obviously:

a1 = x % r
a2 = (x - a1) / r % r 
   or a2 = x / r & % r relying on the integer-division as implemented in  java
a3 = x / r^2 % r
...

an = x / r^(n - 1)%r

This sequence breaks off when an == 0 holds.

This could be implemented in this manner:

list a
while x != 0
    a.add(x % r)
    x /= r

After completion a is the list [a1, a2, ...].

The code in the provided link basically goes the reverse way (starting from the highest to the lowest digit), which solves the problem of keeping a list of digits. A translation of that code would look like this:

pow = floor(log(K, x))

while pow > 0
    digit = floor(x / pow)
    print(digit)

    x -= digit * pow
    pow /= K

Translating a digit as Integer-value to the corresponding char

Translating a digit to a character can be done using a few of the properties of ASCII (java actually uses unicode, but for this problem that doesn't matter). A character is just a number that gets interpreted differently. E.g. 'A' == 64 will return true. All decimal digits are sorted ascendingly and characters are sorted alphabetically. So we can use this to build our table:

digitToChar(digit)
    if digit < 10
        return '0' + digit
    else
        return 'A' + digit - 10

Alternatively, we can just build a table and do our lookups on that table. Since we only need to support up to base 16, we need a table for representation of digits up to base 16:

digitRep = {'0', '1', '2', '3', ..., '8', '9', 'A', 'B', ..., 'F'}
digitToChar(digit)
    return digitRep[digit]

Or you can just use a switch-statement as you've used in your code.

Putting it all together

Finally, the actual implementation based on the code provided in the link would look like this:

static final char[] table = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', 
                                        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

public static void main(String[] args) { 
    //read parameters
    int x = Integer.parseInt(args[0]);
    int k = Integer.parseInt(args[1]);

    // set power to the largest power of K that is <= n
    int power = 1;
    while (power <= x/k) {
        power *= k;
    }

    while (power > 0) {
        //retrieve and print the next digit from x
        int digit = x / power;
        System.out.print(table[digit]);

        //update variables for next loop-run
        x -= digit * power;
        power /= k;
    }

    System.out.println();
}

Upvotes: 0

Related Questions