Solution for
Programming Exercise 4.2
THIS PAGE DISCUSSES ONE POSSIBLE SOLUTION to
the following exercise from this on-line
Java textbook.
Exercise 4.2:
The hexadecimal digits are the ordinary, base-10 digits '0' through '9'
plus the letters 'A' through 'F'. In the hexadecimal system, these digits
represent the values 0 through 15, respectively.
Write a function named hexValue that uses a switch
statement to find the hexadecimal value of a given character. The character
is a parameter to the function, and its hexadecimal value is the return value
of the function. You should count lower case letters 'a' through 'f' as having
the same value as the corresponding upper case letters. If the parameter
is not one of the legal hexadecimal digits, return -1 as the value of the
function.
A hexadecimal integer is a sequence of hexadecimal digits, such as 34A7, FF8,
174204, or FADE. If str is a string containing a hexadecimal integer,
then the corresponding base-10 integer can be computed as follows:
value = 0;
for ( i = 0; i < str.length(); i++ )
value = value*16 + hexValue( str.charAt(i) );
Of course, this is not valid if str contains any characters that are
not hexadecimal digits. Write a program that reads a string from the user.
If all the characters in the string are hexadecimal digits, print out the
corresponding base-10 value. If not, print out an error message.
Discussion
The subroutine has a parameter of type char and a return
value of type int. It's easy to write the switch
statement, although it's tedious because of the number of cases.
A little creative cut-and-paste can help. The switch statement
has a default case that covers all the characters that are not
hexadecimal digits. For such characters, a value of -1 is returned.
The subroutine is shown in the program below, and I will not repeat it
here.
In the main program, I will use TextIO.getlnWord() to read
the user's input, rather than TextIO.getln(). This has the
advantage that it will return a non-empty string that is guaranteed not to
contain any blanks. We still have the problem of checking whether the
user's input contains only valid hexadecimal digits. One approach is
to check all the characters first and use a boolean variable
to record whether they are all valid. Let hex be a string
holding the user's input. Then we have:
boolean valid;
valid = true; // Assume that the input is valid, and change our
// mind if we find an invalid character.
for ( i = 0; i < hex.length(); i++ ) {
if ( hexValue(hex.charAt(i)) == -1 ) { // Character number i is bad.
valid = false;
break; // Leave the for loop, since we are now sure of the answer.
}
}
if ( valid ) { // If the input is valid, compute and print base-10 value
dec = 0;
for ( i = 0; i < hex.length(); i++ )
dec = 16*dec + hexValue( hex.charAt(i) );
System.out.println("Base-10 value is: " + dec);
}
else { // Input is not valid, print an error message
System.out.println("Error: Input is not a hexadecimal number.");
}
This works, but we have to process the string twice. We can avoid
this by checking the input at the same time that we do the conversion.
If the input is illegal, I want to end the program. I use the fact that
a return statement in the main() routine will end
the program, since it returns control back to the system:
dec = 0;
for ( i = 0; i < hex.length(); i++) {
int digit = hexValue( hex.charAt(i) );
if (digit == -1) {
TextIO.putln("Error: Input is not a hexadecimal number.");
return;
}
dec = 16*dec + digit;
}
TextIO.putln("Base-10 value: " + dec);
This is the code that is used in the main() routine of the
program to do the conversion. Note that I declared dec to be
of type long to allow bigger values
than would fit in a variable of type int. The program still has
a problem if the user enters too many characters. (It gets the wrong answer.)
It would probably be better to write a function to do the conversion
of a string to base-10. It could return a -1 if the string is not a legal
hexadecimal number. The main() routine could then call the
function and check its return value to find out whether there was an error.
The Solution
public class Hex2Dec {
/* This program reads a hexadecimal number input by the
user and prints the base-10 equivalent. If the input
contains characters that are not hexadecimal numbers,
then an error message is printed.
*/
public static void main(String[] args) {
String hex; // Input from user, containing a hexadecimal number.
long dec; // Decimal (base-10) equivalent of hexadecimal number.
int i; // A position in hex, from 0 to hex.length()-1.
TextIO.put("Enter a hexadecimal number: ");
hex = TextIO.getlnWord();
dec = 0;
for ( i = 0; i < hex.length(); i++ ) {
int digit = hexValue( hex.charAt(i) );
if (digit == -1) {
TextIO.putln("Error: Input is not a hexadecimal number.");
return;
}
dec = 16*dec + digit;
}
TextIO.putln("Base-10 value: " + dec);
} // end main()
static int hexValue(char ch) {
// Returns the hexadecimal value of ch, or returns
// -1 if ch is not one of the hexadecimal digits.
switch (ch) {
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
default:
return -1;
}
} // end hexValue()
} // end class
[ Exercises
| Chapter Index
| Main Index
]