
| FUNCTION: Hex2Dec().
This useful function takes a hexadecimal word in string format its
argument and converts it into the denary form, returning this as
an integer. This code will only do conversions up to the maximum possible value of its return integer parameter. So, when declaring Hex2Dec(), its paramater must be declared as type int, uint, etc. See the table below for the limits. |
|
Type
|
Exponent
of 2 |
Value
|
| int | 230 | 1073741824 |
| uint | 231 | 2147483648 |
| int64 | 261 | 2305843009213693952 |
| uint64 | 262 | 4611686018427387904 |
|
Declaring the function must be done like
this:
declare Hex2Dec(h: string) Here's the code: sub Hex2Dec(h$) ' Argument h$ must be a string-formatted ' hexadecimal number. Function converts ' it to denary and returns as integer. def ascii, dec, L, p, temp: int L = len(h$) dec = 0: 'initialise denary value for p = 1 to L: 'points to each character 'convert character to ascii ascii = asc(mid$(h$, p, 1)) select 1 ' case 0 to 9 case (ascii > 47 & ascii < 58) temp = ascii - 48 ' case A to F case (ascii > 64 & ascii < 71) temp = ascii - 55 default: 'error condition print "Error!" end endselect 'convert character to denary & totalise dec = dec + temp*16^(L - p) next p return dec |
| Inset
is a simple flowchart which describes the algorithm used. Each
character is inspected one at a time. If it's in the range zero
to nine inclusive, no initial correction will be necessary. If
it's A, B, C, D, E, or F it will need to be corrected to value 10 to 15
respectively. Next comes correction for position. For example, in denary the leftmost digit of the number 37 really means "3 x 10 = 30." Similarly, the leftmost digit in the hexadecimal number B5 really means "B x 16 = B0." Note that B0 in hex is 176 in denary! All the characters are dealt with in the same way until the whole conversion is complete. |
![]() |
| The following
lines of code do all the work. I've numbered them to make
explanations simpler. |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
L = len(h$) dec = 0 for p = 1 to L ascii = asc(mid$(h$, p, 1)) select 1 case (ascii > 47 & ascii < 58) temp = ascii - 48 case (ascii > 64 & ascii < 71) temp = ascii - 55 default print "Error!" end endselect dec = dec + temp*16^(L - p) next p return dec |
| Let's
look at the above code in detail now, using those line numbers. |
| 1 |
L = len(h$). Variable L is inialised to hold the number of characters in variable h$. For example, if h$ is "AFC" the L will be loaded with 3. |
| 2 |
dec = 0. Variable dec will eventually hold the denary value of the function's argument, h$, so it's initialised here to zero. |
| 3 |
for p = 1 to L. Opens the main for-next loop, using variable p. p is an abbreviation for pointer. It is used to point at each character in h$ one at a time. The range is from the first character to L, which is just the length of h$, so that each and every character is inspected one at a time and in order. |
| 4 |
ascii = asc(mid$(h$, p, 1)).
Line 4 addresses the problem of dealing with characters that can be
ordinary digits ( o - 9) or alpha's (A - F). It will encode it in
a manner which will make it translatable to denary. Let's look at
the line from the inside.
|
| 5 |
select 1. The code will now deal with the value stored in variable ascii, using the select-case method. |
| 6 |
case (ascii > 47 & ascii < 58). We deal firstly with the case where variable ascii's
stored value lies between 48 and 57, which occurs when we are dealing
with a hexadecimal character from 0 to 9. The required action is spelt out in line 7. |
| 7 |
temp = ascii - 48. In the case that ascii holds a value in the range 48 - 57, we can convert it directly back to a decimal value, and this is accomplished by subtracting 58 from that value. The result is stored in variable temp. |
| 8 |
case (ascii > 64 & ascii < 71). This is the second case, which occurs when dealing with the characters A to F. The action is shown in line 9. |
| 9 |
temp = ascii - 55. In this case, the code converts the values A through F into the decimal equivalent of 10 through 15 by subtracting 55 from the stored value in variable ascii and saving it in variable temp. |
| 10 |
default. Normally the program will have found an acceptable case as above, and will skip directly from there to line 13. However, line 10 provides a safety net. If the calling routine has inadvertently passed an illegal character to function Hex2Dec, such as "Q" for instance, it will be caught as a default. Appropriate action is dictated in line 11. |
| 11 |
print "Error!". If the calling routine passes an illegal character to the function, this error message will be printed to the computer screen. |
| 12 |
end. There is no point continuing with the program if illegal characters are being fed to it, and the line 12 terminates it. |
| 13 |
endselect. Housekeeping: closes the select-endselect clause opened in line 5. |
| 14 |
dec = dec + temp*16^(L - p).
The code now makes the correction for position shown in the flowchart
above. The formula shown here includes the correction and
totalises the corrected figure in variable dec. Here's an example, for, say, the hexadecimal word "C3," looking at the first character (C). The value of L here will be 2, the length of the word. The pointer p will be 1, pointing at the first character. Variable temp will be 12, the value of C after passing through the ascii process. Finally, dec will hold zero at this time. So our formula now reads dec = 0 + 12 x 16(2-1) which evaluates correctly to 192. |
| 15 |
next p. Housekeeping: closes the for-next loop opened in line 3. |
| 16 |
return dec. The code has now finished the conversion, and the hexadecimal argument's value has been converted into denary and totalised into variable dec. All that's necessary is to return this value to the calling routine. |
MAIN MENU
HOW DOES IT WORK?
Site design/maintenance: Dave Ellis E-mail me!
Last Updated: February 4th, 2010.