Thread: Hex String to Decimal converter

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    5

    Hex String to Decimal converter

    I need to write a function that takes in only a string representing a hex number and returns its decimal equivalent, or -1 if the string connotes to a negative number / has any invalid characters. I cant use any library functions in this function and it must be case insensitive.

    Ive started to code it but im stuck. I started by checking if all of the characters were valid by checking there ASCII values but i dont really know where to go from here.

    Code:
    int hexToDecimal(char * str)
    {
    	int i;
    	
    	for(i = 0; str[i] != '\0'; i++)
    	{
    		if( ( (int) str[i] < 48 || (int) str[i] > 57) && ( (int) str[i] < 65 || 
                              (int) str[i] > 70) && ( (int) str[i] < 97  || (int) str[i] > 102 ))
    			return -1;
    
    	return 0;
    }

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Do you know how to convert from base-16 to base-10?

    0x1B in decimal;
    Code:
    1B
    = 1 11
    = 1*16^1 + 11*16^0
    = 16 + 11
    = 27
    You may want to look into using horner's method
    Last edited by zacs7; 11-04-2008 at 10:11 PM.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    5
    Yeah i do but maybe not in the right way for this. I've added this:

    Code:
    int hexToDecimal(char * str)
    {
    	int i, count = 0, temp, sum = 0;
    	
    	for(i = 0; str[i] != '\0'; i++)
    	{
    		if( ( (int) str[i] < 48 || (int) str[i] > 57) && ( (int) str[i] < 65 || (int) str[i] > 70) && ( (int) str[i] < 97  || (int) str[i] > 102 ))
    			return -1;
    		count++;
    	}
    
    	for(count; count >= 0; count--)
    	{
    		if( (int) str[count] >= 48 && (int) str[count] <= 57)
    			temp = (int) str[count] - 48;
    		else if ( (int) str[count] >= 65 && (int) str[count] <= 70)
    			temp = (int) str[count] - 55;
    		else
    			temp = (int) str[count] - 87;
    
    	}
    	
    	printf("%i\n", temp);  //just checking that the ascii values converted right
    
    	return 0;
    }
    I am thinking that i can using my for loop i can take whatever temp is and multiple it by 16^i where i is the current iteration. The only thing is that i need the pow function.

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    I edited my post, don't use pow() -- look into horner's method. Try and use ASCII values, rather than their constant equivalents.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    1. Magic numbers (48, 57, etc.) bad. 2. Those casts to int aren't needed.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Don't see where you are returning the decimal equivalent of a hex string. Seems to me you're returning 0 to the caller.

  7. #7
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    > Don't see where you are returning the decimal equivalent of a hex string. Seems to me you're returning 0 to the caller.
    If you read the post, you'd see he hasn't finished it yet.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Ah! I see the OP inserted a new one while I was replying to the original.

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    5
    Okay so i got rid of the int cast for some reason it didn't work earlier without it must have messed something up. Thanks for horners method, i was planning on doing something like that but how can i do it without pow? Unless i am mistaken (very possible) in order to do 16^0, 16^1 i need pow. Also how should i do it by keeping the ASCII values?
    Last edited by wrex; 11-04-2008 at 10:45 PM.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    16^1 is 16. All you do every time is (1) multiply by 16 (2) add the digit you're looking at. I think zacs' suggestion about ASCII and my suggestion about ASCII are the same -- don't write 48, write '0'. Don't write 57, write '9'. This way you and everyone knows what the heck is going on.

  11. #11
    Registered User
    Join Date
    Nov 2008
    Posts
    5
    Yeah i get that part but my question is how do i do 16 ^ 1, 16 ^ 2. As far as i know there is no ^ operator and you have to use the pow function. I have tried using bitwise arithmatic and i think it works but something else is wrong with my code. It is only doing the first char entered even though i want it to start at the last index.

    Code:
    int hexToDecimal(char * str)
    {
    	int i, count = 0, temp, sum = 0, j = -2;
    	
    	for(i = 0; str[i] != '\0'; i++)
    	{
    		if( (str[i] < 48 || str[i] > 57) && (str[i] < 65 || str[i] > 70) && ( str[i] < 97  ||  str[i] > 102 ))
    			return -1;
    		count++;
    	}
    
    	count--;
    
    	for(count; count >= 0; count--)
    	{
    		if(  str[count] >= '0' &&  str[count] <= '9')
    			temp = str[count] - 48;
    		else if ( str[count] >= 'A' &&  str[count] <= 'F')
    			temp = str[count] - 55;
    		else
    			temp =  str[count] - 87;
    
    		for(i = 0; i < count; i++)
    			temp = temp * 16 << (j +2);
    
    	}
    
    	printf("&#37;i\n", temp);
    
    	return temp;
    Last edited by wrex; 11-05-2008 at 01:16 AM.

  12. #12
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    It's pointless asking for help if you don't do what we say.

    Sure you can use bitwise ops to get 16 (2^4). But if you use horner's method, it's much faster and you can do bigger numbers (due to overflow being removed at each stage).

    Summing up the previous posts;
    1. Use horner's method. tabstop explained how
    2. Avoid magic numbers, use '0' instead of 48 etc.
    3. Those int casts are not needed

    You do not need pow(), even if you wanted to do it the "slow" way then you could simply implement a loop to get the Nth power of 16. You should know that, 16^2 = 16 * 16. Likewise, 16^4 = 16 * 16 * 16 * 16

  13. #13
    Registered User
    Join Date
    Nov 2008
    Posts
    5
    Quote Originally Posted by zacs7 View Post
    It's pointless asking for help if you don't do what we say.

    Sure you can use bitwise ops to get 16 (2^4). But if you use horner's method, it's much faster and you can do bigger numbers (due to overflow being removed at each stage).

    Summing up the previous posts;
    1. Use horner's method. tabstop explained how
    2. Avoid magic numbers, use '0' instead of 48 etc.
    3. Those int casts are not needed

    You do not need pow(), even if you wanted to do it the "slow" way then you could simply implement a loop to get the Nth power of 16. You should know that, 16^2 = 16 * 16. Likewise, 16^4 = 16 * 16 * 16 * 16
    Im not trying to ignore what your saying but its either not making since to me or not working when i try it (combination of both).

    I did change the comparisons from ASCII to 'A'. However i tried to change the assignments from str[count] to temp without using the ASCII numbers and it did not work. The "magic numbers" ASCII way is the only way my teacher taught us and i was not aware it was bad programming.

    I also did what you recommended and took away the int cast in the code i last posted.

    I understand horners method but im not understanding how to implement it. I cannot think of a way to keep on adding powers of 16 depending on the digit place. I need to be able to write code that can convert E1 and A23. For E1 i would do 1 * 16^0 + 14 * 16^1, while for A23 i would need to do 3 * 16^0 + 2 * 16^1 + 10 * 16^2.

  14. #14
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    A23 in horner's method is

    Code:
    = A23
    = 10 23
    
    # start off with 0
    result = 0
    
    (add result and 10 together -- ie the first digit)
    = result + 10 = 10
    (multiply that by 16)
    = 10 * 16 = 160
    
    (160 so far)
    result = 160
    
    (add 2 to the result -- ie the 2nd digit)
    = result + 2 = 162
    (multiply that by 16)
    = 162 * 16 = 2592
    
    result = 2592
    
    (add the last digit to result)
    = result + 3 = 2595
    
    result = 2595
    Notice no powers of 16. That is only 2 multiplications... you have not been using horner's method. That should be easily enough to implement in C
    Last edited by zacs7; 11-05-2008 at 01:37 AM.

  15. #15
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    strtol()

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Hex String to Decimal Possible?
    By someprogr in forum C Programming
    Replies: 4
    Last Post: 02-01-2009, 01:47 AM
  3. Signed hex string to a int
    By naruto267 in forum C Programming
    Replies: 5
    Last Post: 05-18-2008, 11:43 PM
  4. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  5. Converting a binary string to hex
    By maxhavoc in forum C++ Programming
    Replies: 6
    Last Post: 07-25-2006, 12:46 PM