Link to home
Start Free TrialLog in
Avatar of Mike Eghtebas
Mike EghtebasFlag for United States of America

asked on

hex conversion...

At line:

        try{

            if (ch<'0' || ch>'F')
                throw new NumberFormatException("not a hex number.");
.
.

When ch is G, it doesn't throw "not a hex number." error?

Q1: 'G' > 'F', why then this doesn't work.
Q2: What happens if the data supplied is lower case? like g in place of G or b in place of B?

Thank you.
import java.util.Scanner;

public class Exercise13_6{

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("Enter a hex number: ");
        String hex=input.nextLine();

        System.out.println("The decimal value for hex number "
                + hex + " is " + hexToDecimal(hex.toUpperCase()));
    }

    public static int hexToDecimal(String hex) {
        int decimalValue=0;
        for(int i=0; i<hex.length();i++) {
            char hexChar=hex.charAt(i);
            decimalValue=decimalValue*16+hexToDecimal(hexChar);
        }
            return decimalValue;
    }

    public static int hexToDecimal(char ch)  {

        int temp=0;
        try{

            if (ch<'0' || ch>'F')
                throw new NumberFormatException("not a hex number.");

            if (ch>='A' && ch <='F')
                temp = 10+ch-'A';
            else
                temp = ch-'0';

        }catch (NumberFormatException ex){
//                         ex.printStackTrace();

        }
        return temp;
    }
}

Open in new window

Avatar of for_yan
for_yan
Flag of United States of America image


This works for me:
 
 char    cc = 'G';

        if(cc < '0' || cc > 'F')   System.out.println("bigger");

Open in new window

There is a method hex to int you don't need to write it
That is becaiue you have additional catch loop there
 public static int hexToDecimal(char ch) throws NumberFormatException {

        int temp=0;
        

            if (ch<'0' || ch>'F')
                throw new NumberFormatException("not a hex number.");

            if (ch>='A' && ch <='F')
                temp = 10+ch-'A';
            else
                temp = ch-'0';

            return temp;
    }

Open in new window

You were catching it in the additional catch loop and even not printing the stackTrace - so uyou just caught the exception and
didn't inform anyoje about it - and you didn't see that it was throwing it - the above post should work
That's how it works:

public class TryHexToDecimal {
 public static int hexToDecimal(char ch) throws NumberFormatException {

           int temp=0;
           

               if (ch<'0' || ch>'F')
                   throw new NumberFormatException("not a hex number.");

               if (ch>='A' && ch <='F')
                   temp = 10+ch-'A';
               else
                   temp = ch-'0';


           return temp;
       }



    public static void main(String[] args) {

        System.out.println(hexToDecimal('G'));

}
}

Open in new window


Exception in thread "main" java.lang.NumberFormatException: not a hex number.
	at Miscellaneous.hexToDecimal(Miscellaneous.java:24)
	at Miscellaneous.main(Miscellaneous.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)

Open in new window

lowercase is bigger than upper case
so

'a' > 'F'

so it will cause exception also

so you want to do something like that:
   boolean good = false;
        if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))good = true;
        
               if (!good) 
                   throw new NumberFormatException("not a hex number.");

Open in new window


But then you should take care of another oart where uyou
should assign values to a-f lowere case

Instead of doing all that just use the method
which makes int out of hex string which I posted above



and maybe even better method:
http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#parseInt%28java.lang.String,%20int%29

int i = Integer.parseInt(String s, int radix)

This is how it parseInt() method works:

    int inum = Integer.parseInt("12Fc10",16);

        System.out.println("inum: " + inum);
        

Open in new window


Output:
inum: 1244176

Open in new window


          int inum1 = Integer.parseInt("12Fc10g",16);

Open in new window


Output:

Exception in thread "main" java.lang.NumberFormatException: For input string: "12Fc10g"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
	at java.lang.Integer.parseInt(Integer.java:458)
	at Miscellaneous.main(Miscellaneous.java:47)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)

Open in new window

Avatar of Mike Eghtebas

ASKER

On the original issue, I am getting error message like:

Enter a hex number: k
Exception in thread "main" java.lang.NumberFormatException: K is not a hex number.
      at Exercise13_6.hexToDecimal(Exercise13_6.java:31)
      at Exercise13_6.hexToDecimal(Exercise13_6.java:21)
      at Exercise13_6.main(Exercise13_6.java:13)
Java Result: 1
BUILD SUCCESSFUL (total time: 4 seconds)

Where I just want:

K is not a hex
import java.util.Scanner;

public class Exercise13_6{

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);


        System.out.print("Enter a hex number: ");
        String hex=input.nextLine();

        System.out.println("The decimal value for hex number "
                + hex + " is " + hexToDecimal(hex.toUpperCase()));
    }

    public static int hexToDecimal(String hex) {
        int decimalValue=0;
        for(int i=0; i<hex.length();i++) {
            char hexChar=hex.charAt(i);
            decimalValue=decimalValue*16+hexToDecimal(hexChar);
        }
            return decimalValue;
    }

//    public static int hexToDecimal(char ch)  {
public static int hexToDecimal(char ch) throws NumberFormatException {
        int temp=0;
        
               if (ch<'0' || ch>'F')
                   throw new NumberFormatException(ch + " is not a hex number.");

               if (ch>='A' && ch <='F')
                   temp = 10+ch-'A';
               else
                   temp = ch-'0';


           return temp;        

    }
}

Open in new window

You need to define your own custom Exception and
after you catcgh NumberFormat throw your Custom exception - look
at our previous exrcises  where you were doing calculator
 
Or you can do it like that - catch it
but not print the exception with toString() or with ex.printStackTrace()
but rather print your own message:

 public static int hexToDecimal(char ch)  {

           int temp=0;
           
        try{
        boolean good = false;
        if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))good = true;

               if (!good)
                   throw new NumberFormatException("not a hex number.");

               if (ch>='A' && ch <='F')
                   temp = 10+ch-'A';
               else
                   temp = ch-'0';
            
        } catch(Exception ex){
            System.out.println("Not a hex");
            
        }


           return temp;
       }

Open in new window

Thanks I guess I can handle this.
Say, like that:

pubblic class HandlingExcept {  
public static int hexToDecimal(char ch)  {

           int temp=0;

        try{
        boolean good = false;
        if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))good = true;

               if (!good)
                   throw new NumberFormatException("not a hex number.");

               if (ch>='A' && ch <='F')
                   temp = 10+ch-'A';
               else
                   temp = ch-'0';

        } catch(Exception ex){
            System.out.println(ch + " is not a hex character");

        }


           return temp;
       }



    public static void main(String[] args) {

       System.out.println(hexToDecimal('g'));
}
}

Open in new window


g is not a hex character

Open in new window

I still need to read some of your last emails...

This is what I have so far, but it has one error:
import java.util.Scanner;

public class Exercise13_6{

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter a hex number: ");
        String hex=input.nextLine();
        System.out.println("The decimal value for hex number "
                + hex + " is " + hexToDecimal(hex.toUpperCase()));
    }

    public static int hexToDecimal(String hex) {
        int decimalValue=0;
        for(int i=0; i<hex.length();i++) {
            char hexChar=hex.charAt(i);
            decimalValue=decimalValue*16+hexToDecimal(hexChar);
        }
            return decimalValue;
    }

    public static int hexToDecimal(char ch) throws
        InvalidDataException13_6, NumberFormatException {
        int temp=0;
        boolean good = false;
        
        try{
            if((ch >= '0' && ch <= 'F')  || 
               (ch >= 'a' && ch <= 'f'))good = true;

               if (!good) //{
                   throw new InvalidDataException13_6(ch+" is not a hex number.");
//               }else{
                   if (ch>='A' && ch <='F')
                       temp = 10+ch-'A';
                   else
                       temp = ch-'0';
//               }
        } catch(Exception ex){
//            System.out.println("Not a hex");
            throw new InvalidDataException13_6 (ch+" is not a hex number.");
        }
           return temp;
    }
}

class InvalidDataException13_6 extends Exception { 
    private String mistake;
    public  InvalidDataException13_6(String err)
     {
       super(err);     // call super class constructor
       mistake = err;  // save message
     }

    public String toString(){
        return mistake;
    }
}

Open in new window

I guess I have it now
import java.util.Scanner;

public class Exercise13_6{

    public static void main(String[] args) throws
        InvalidDataException13_6, NumberFormatException {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter a hex number: ");
        String hex=input.nextLine();
        System.out.println("The decimal value for hex number "
                + hex + " is " + hexToDecimal(hex.toUpperCase()));
    }

    public static int hexToDecimal(String hex) throws
        InvalidDataException13_6, NumberFormatException {
        int decimalValue=0;
        for(int i=0; i<hex.length();i++) {
            char hexChar=hex.charAt(i);
            decimalValue=decimalValue*16+hexToDecimal(hexChar);
        }
            return decimalValue;
    }

    public static int hexToDecimal(char ch) throws
        InvalidDataException13_6, NumberFormatException {
        int temp=0;
        try{
            if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))//good = true;
               throw new InvalidDataException13_6(ch+" is not a hex number.");
                   if (ch>='A' && ch <='F')
                       temp = 10+ch-'A';
                   else
                       temp = ch-'0';
        } catch(Exception ex){
            throw new InvalidDataException13_6 (ch+" is not a hex number.");
        }
           return temp;
    }
}

class InvalidDataException13_6 extends Exception { 
    private String mistake;
    public  InvalidDataException13_6(String err)
     {
       super(err);     // call super class constructor
       mistake = err;  // save message
     }

    public String toString(){
        return mistake;
    }
}

Open in new window

not quite there yet.
Seems OK, but I'm not sure if it will be lower case, this part will work correctly:

 if (ch>='A' && ch <='F')
                       temp = 10+ch-'A';
                   else
                       temp = ch-'0';

and if ch = 'b' - ?
Avatar of CEHJ
>>
         if (((ch >= '0') && (ch <= 'F')) || ((ch >= 'a') && (ch <= 'f'))) { //good = true;
                throw new InvalidDataException13_6(ch +
                    " is not a hex number.");
            }
>>

Your logic is the wrong way around there
I ran for k, this is whay I got:

run:
Enter a hex number: k
The decimal value for hex number k is 27
BUILD SUCCESSFUL (total time: 5 seconds)

which is wrong result.  and:

Enter a hex number: A22
Exception in thread "main" A is not a hex number.
      at Exercise13_6.hexToDecimal(Exercise13_6.java:35)
      at Exercise13_6.hexToDecimal(Exercise13_6.java:19)
      at Exercise13_6.main(Exercise13_6.java:10)
Java Result: 1
BUILD SUCCESSFUL (total time: 7 seconds)

re:> Your logic is the wrong way around there

I will revise and test it again
Use this logic :

  boolean good = false;
        if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))good = true;

               if (!good)
                   throw new NumberFormatException("not a hex number.");

Open in new window


but rervise the part where you calculate the actuall value form lower case - it should be sdifferent
OK
I think this should work:

  public static int hexToDecimal(char ch)  {

           int temp=0;

        try{
        boolean good = false;
        if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))good = true;

               if (!good)
                   throw new NumberFormatException("not a hex number.");

               if (Character.toUpperCase(ch)>='A' && Character.toUpperCase(ch)<='F')
                   temp = 10+Character.toUpperCase(ch)-'A';
               else
                   temp = Character.toUpperCase(ch)-'0';

        } catch(Exception ex){
            System.out.println(ch + " is not a hex character");

        }


           return temp;
       }

Open in new window

Or just convert your character to upper case form the very nebgging and that will make your code
mauch easier (baseically like it was in the beginning)
>>  if((ch >= '0' && ch <= 'F')  || (ch >= 'a' && ch <= 'f'))good = true;

Won't work unfortunately - it will set good to true for '@'

You'd be better off with
ch = Character.toLowerCase(ch);
good = "0123456789abcdef".indexOf(ch) > -1;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>if (Character.toUpperCase(ch)>='A' && Character.toUpperCase(ch)<='F')

Don't do that. Convert it straight away and call the method once, not multiple times
Well, in the end use, parseInt as I mentioned above - this is definitely something wahich you sdon't want to write yourself
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>this is definitely something wahich you sdon't want to write yourself

Well i think that goes without saying, outside an academic exercise, which is what i assume this is
>>I think this should also work:

It doesn't - for the reason i gave at http:#:36945129


Can you tell me why you accepted an incorrect answer eghtebas?