2

Background:

I am making a simple base converter for a class assignment. I am fairly close to completion but need to tidy up the conversion algorithm to convert the user inputted value (in a given base) to a base 10 value.

Attempt:

import java.util.Scanner;

public class BaseConverter {
public static void main(String[] args) {
    String numIn, intro1, prompt1, prompt2, output1;
    int baseIn;
    double numOut;
    boolean flag = true;
    Scanner kb = new Scanner(System.in);

    intro1 = "This program converts values in different number bases to a decimal value.";
    prompt1 = "Type in a number base (2 - 9): ";

    while (flag == true){
        System.out.println(intro1);
        System.out.println(prompt1);
        baseIn = kb.nextInt();
        //Checking base value for outliers outside given range
        if (baseIn < 2 || baseIn > 9) {
            System.out.println("Base must be between 2 and 9");
            System.exit(1);
        }
        prompt2 = "Type in a base "+baseIn+" number: ";
        System.out.println(prompt2);
        numIn = kb.next();

        // System.out.println(numStore);
        int counter = 0;
        // Let's pretend baseIn is 3 and i starts at 3 
        for (int i = numIn.length(); i >= 1; i--){
            numOut = (numIn.charAt(i-1) * Math.pow(baseIn, counter++));
            System.out.println(numOut);
        }
    }//while
}// method
}//class

The problem:

This line does not return the expected value

numOut = (numIn.charAt(i-1) * Math.pow(baseIn, counter++));

For example, in string "10", numOut should be (0*(2*0)) or zero on the first iteration of the for loop. Instead, it returns 48.0.

My Thoughts:

I have a sneaking suspicion it has to do with the charAt() method as debugging the Math.pow() method showed it returning expected values. Suppose it's something to do with all the different variable types? I'm unsure.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
jclark754
  • 914
  • 2
  • 12
  • 30
  • 1
    A "character", in Java, is a numeric value which tells you where the character can be found in an (for current purposes) [ASCII table](http://www.asciitable.com/index/asciifull.gif). The character "0", for instance, has a value of 48 decimal. (The same is true for "characters" in virtually all programming languages.) – Hot Licks Feb 11 '15 at 00:38
  • 1
    (The more complete answer, many would insist on telling me, is that the value is a UNICODE value. But the first 128 characters of UNICODE are essentially the same as ASCII, and an ASCII table is much easier to read.) – Hot Licks Feb 11 '15 at 00:41
  • java.lang.Long has a method `public static long parseLong(String s, int radix)` – javamonk Feb 11 '15 at 00:48

2 Answers2

5

Yes you're right charAt is the problem.

When you type let's say "10", the integer value of the character '0' is 48 and for '1' it's 49 according to the encoding table Java uses to encode characters.

enter image description here

If you take a look at it, you see that 0 is encoded as 0x0030 = 3*16^1 = 48, 1 as 0x0031 = 3*16^1 + 1*16^0 = 49 and so on.

If you want to get the numeric value of the character itself you can use

numOut = Character.getNumericValue(numIn.charAt(i-1)) * Math.pow(baseIn, counter++);
Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • I appreciate your thorough explanation on this. When i implement the given line, an error is thrown "The method getNumericValue(char) in the type Character is not applicable for the arguments (double)", any thoughts? The suggested fix is to cast (char), but this does not resolve the issue. – jclark754 Feb 11 '15 at 00:50
  • @jclark754 Sorry I mixed up the parenthesis (there was one missing), I just edited the answer. It should work as expected now. – Alexis C. Feb 11 '15 at 00:52
2

The charAt method returns the char of your input, in this case '0', not 0. The Unicode value for the char '0' is not 0, it's 48.

Fortunately, the values '0' through '9' are consecutive Unicode values, 48 through 57 respectively, so you can "subtract" out the 48 by subtracting '0' before multiplying.

numOut = ( (numIn.charAt(i-1) - '0') * Math.pow(baseIn, counter++));

You'll still need to validate that what the user typed is in fact a valid "digit" in the chosen base.

You'll also want to add the values of numOut together to get the decimal result at the end.

rgettman
  • 176,041
  • 30
  • 275
  • 357