Hex String to Decimal converter

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 11-04-2008
wrex
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;
}

• 11-04-2008
zacs7
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
• 11-04-2008
wrex
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.
• 11-04-2008
zacs7
I edited my post, don't use pow() -- look into horner's method. Try and use ASCII values, rather than their constant equivalents.
• 11-04-2008
tabstop
1. Magic numbers (48, 57, etc.) bad. 2. Those casts to int aren't needed.
• 11-04-2008
itCbitC
Don't see where you are returning the decimal equivalent of a hex string. Seems to me you're returning 0 to the caller.
• 11-04-2008
zacs7
> 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.
• 11-04-2008
itCbitC
Ah! I see the OP inserted a new one while I was replying to the original.
• 11-04-2008
wrex
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?
• 11-04-2008
tabstop
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-04-2008
wrex
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;

• 11-04-2008
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
• 11-05-2008
wrex
Quote:

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.
• 11-05-2008
zacs7
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 :)
• 11-05-2008
master5001
strtol()
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last