THE PUZZLET PAGE


How_Does_It_Work


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.

Argument
Argument % 7
n$
Argument/7
2129
1
"1"
304
304
3
"31"
43
43
1
"131"
6
6
6
"6131"
0

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.