contextBaseN.pl - Implements a MathObject class and context for numbers in non-decimal bases
This context implements positive integers and some operations on integers in a non-decimal base greater than or equal to 2. The numbers will be stored internally in decimal, though parsed and shown in the chosen base.
In addition, basic integer arithemetic (+,-,*,/,%,^) are available for these numbers. Division is defined in an integer sense.
The original purpose for this is simple conversion and operations in another base, however it is not limited to this.
To use a non-decimal base MathObject, first load the contextBaseN.pl file:
loadMacros('contextBaseN.pl');
There are two contexts: BaseN
and LimitedBaseN
, where the former allows operations between numbers and the latter only allows numbers. To use either, one must set the base. For example:
Context('BaseN')->setBase(5);
Now most numerical strings in Compute, Formula, and student answers will be read in base five.
$a = Compute('104');
$b = Compute('233');
$sum = $a+$b # this is the base-5 number 342 (decimal 97)
or a shorter way:
$sum = Compute('104+233');
Also, when a string is the argument to some other Math Object and that string needs to be parsed, numerical substrings will be read in base 5:
$point = Point('(104, 233)'); # this is (29, 68) in base ten
For Math Object constructors that directly accept a number or numbers as arguments, the numbers will be read in base ten. All of the following should be read in base ten:
$r = Real(29);
$r = Real('68');
$p = Point(29, 68);
For many problems, one may wish to not allow operators in the student answers. Use 'LimitedBaseN' for this.
Context('LimitedBaseN')->setBase(5);
$sum = Compute("104+233"); # There will be an error on this line now.
In both contexts, rather than pass the base as a number, another option is to pass the digits used for the number to the setBase
method. For example, if one wants to use base-12 and use the alternative digits 0..9,'T','E', then
Context('BaseN')->setBase([0 .. 9, 'T', 'E']);
Then one can use the digits 'T' and 'E' in a number like:
Compute('9TE');
A few strings can be passed to the setBase
method with preset meanings:
C<binary> for [0,1]
C<octal> for [0 .. 7]
C<decimal> for [0 .. 9]
C<duodecimal> for [0 .. 9, 'A', 'B']
C<hexadecimal> for [0 .. 9, 'A' .. 'F']
C<base64> for ['A' .. 'Z', 'a' .. 'z', 0 .. 9, '_', '?']
The last two digits for base64
are nonstandard. We want to avoid '+' and '/' here as they have arithmetic meaning.
A simple PG problem that asks a student to convert a number into base-5:
DOCUMENT();
loadMacros(qw(PGstandard.pl PGML.pl contextBaseN.pl));
Context('LimitedBaseN')->setBase(5);
# decimal number picked randomly.
$a = random(130,500);
$a_5 = Real($a); # converts $a to base-5
BEGIN_PGML
Convert [$a] to base-5:
[$a] = [__]*{$a_5}
END_PGML
ENDDOCUMENT();
The star variant answer blank will print the base in subscript after the answer blank.
The function convertBase(value, opts)
converts the value from or to other bases depending on the options in opts
. The input value
is a positive number or string version of a positive number in some base.
from
the base that value
is in. Default is 10. Can take the same values as setBase
.
to
the base that value
will be converted to. Default is 10. Can take the same values as setBase
.
For the following, since from
is not used, the base of value
is assumed to be 10.
convertBase(58, to => 5); # returns 213
convertBase(58, to => 8); # returns 72
convertBase(734, to => 16); # returns 2DE
For the following, since to
is not used, these are converted to base 10.
convertBase(213, from => 5); # returns 58
convertBase(72, from => 8); # returns 58
convertBase('2DE', from => 16); # returns 734
Both to
and from
can be used together.
convertBase(213, from => 5, to => 8); # returns 72
If one wants to use a different set of digits, say 0..9, 'T', 'E' for base-12 as an example
convertBase(565, to => [0 .. 9, 'T', 'E']); # returns '3E1'