NAME

contextBaseN.pl - Implements a MathObject class and context for numbers in non-decimal bases

DESCRIPTION

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.

Sample PG problem

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.

convertBase

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.

options

Examples

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'