# Thread: Hex String to Decimal converter

1. ## 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. 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

3. 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. I edited my post, don't use pow() -- look into horner's method. Try and use ASCII values, rather than their constant equivalents.

5. 1. Magic numbers (48, 57, etc.) bad. 2. Those casts to int aren't needed.

6. 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. > 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. Ah! I see the OP inserted a new one while I was replying to the original.

9. 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?

10. 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. 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;```

12. 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. Originally Posted by zacs7
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. 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

15. strtol()