
| FUNCTION:
ChangeBase(). This useful function takes a
denary integer as its first argument (a number in base 10 without a
decimal
part) and converts it into a user-specified number base in the range 2
to 9. The returned number is in string format, for two reasons. Firstly, lower base numbers are physically a lot longer than their denary form, and, since IBasic would believe a number such as 10100100011001 etc is denary, could cause an overflow (too big for an integer type). Secondly, the function assembles its output in string format anyway, so no conversion is necessary. This code will only do conversions up to the maximum possible value of its argument. So, when declaring ChangeBase(), its arguments must be declared as type integer (int). 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 ChangeBase(d: int, b: int) (or whatever type of integer you choose). Here's the code: sub ChangeBase(n, b) ' Argument n is the number whose base is ' to be changed: it must be a base 10 ' integer. Argument b is the base to ' which n will be changed: it must be an ' integer from 2 to 9. def temp: int def nStr$: string temp = n nStr$ = "" do nStr$ = ltrim$(str$(temp % b)) + nStr$ temp = temp/b until temp = 0 return nStr$ |
| Overview: the algorithm employed
is the classic one used for this function. The denary argument is
divided by the target base number. The remainder from the division
forms the right-most digit of the result. The process continues until
there is no remainder, when conversion is complete. Here's an example of converting 2129 to base 7.
You can see how this was derived by following the table. After each "test" division by 7, the remainder is tacked onto the left of the existing string, n$. Now a "real" division by 7 takes place, and any decimal part is discarded, creating a new, integer argument. Thus, as the argument gets smaller, the string gets larger. This goes on until the argument shrinks to zero, when the process is complete. Let's take a look now at the local variables used by ChangeBase(). The function's first argument is d, an integer in denary or base 10 format. This is the value which will be converted to some other, lower, number base. The function's second argument is b, an integer used to indicate the number base it is require to convert the first argument to. temp is a copy of argument n. This arrangement is set up because the function will actually change the value of n otherwise. n$ is set up to hold the output. It will be initially an empty string. The next half dozen lines of code do all the work. I've numbered them to make explanations simpler. |
| 1 2 3 4 5 6 7 |
temp
= n nStr$ = "" do nStr$ = ltrim$(str$(temp % b)) + nStr$ temp = temp/b until temp = 0 return nStr$ |
| Let's
look at the above code in detail now. |
| 1 |
temp
= n.
Copies argument n into
variable temp. This ensures
that n's value isn't changed
by the function, as it can now work on temp instead of n. |
| 2 |
nStr$
= "".
Varable n$ will eventually
hold the output of the function, so it must be initialised as an empty
string. |
| 3 |
do. Opens the main DO loop. |
| 4 |
nStr$
= ltrim$(str$(temp
% b)) + nStr$.
This line effectively works out what remainder would exist if the
argument were divided by the target base number and saves that
remainder into the output string. To see how it works, let's
start in the innermost string. Integer arthmetic is deployed here. temp % b is IBasic for "divided the contents of variable temp by the value stored in variable b, keep any remainder, and discard the rest. In our example, converting 2129 to base 7, this would produce 2129 % 7 = 1. The result of the integer arithmetic division is converted into string format, as can be seen by looking at the next level of brackets: str$(temp % b). In our example, this would produce " 1". All basics add a leading space for format reasons when doing this string conversion. In this case, the space would lead to an error, so it must be removed. IBasic's built-in function, ltrim$() is used, which simply means "Trim off the left-most space." Thus we have: ltrim$(str$(temp % b)). You may have noticed the space before the 1 in the example at the end of the preceding paragraph. ltrim$() would remove this, leaving just "1". The rest of the expression concatenates the result of this action onto the left-hand end of variable n$, and then re-saves it as n$, over-writing whatever was already stored there. Since n$ was initialised to the empty string, "", it will now hold, for our example, "1". The second time around the DO loop it will expand to "31" and so on, as shown in the table above. |
| 5 |
temp
= temp/b.
The code just dealt with the remainder from a theoretical division of
the argument d. Now it
has to do the division for real. Line 5 carries out the task for
us. There's one important thing to note here. We already dealt with the remainder, and so it must now be discarded. In "normal" circumstances, given a value of 2129 for temp and 7 for b, the expression temp = temp/b should produce 2129/7 = 304.14. However, in the declaration, variable temp was established as an integer, so the decimal part will be discarded, yielding the required 304. |
| 6 |
until temp = 0. The code has reached the end of its DO loop, and must now make a decision: execute the loop again, or quit. If the last division (line 6) yielded zero, the process is complete. So line 7 could be paraphrased as "if the value stored in variable temp has reduced to zero, quit the DO loop, otherwise execute it again." |
| 7 |
return nStr$. The DO loop will eventually be quit, at which point the number-base conversion is complete. All that is necessary now is to return the changed value to the calling routine, and line 8 does just that. |
MAIN MENU
HOW DOES IT WORK?
Site design/maintenance: Dave Ellis E-mail me!
Last Updated: February 3rd, 2010.