NAME
Math::BaseArith - mixed-base number arithmetic (like APL encode/decode)
SYNOPSIS
use Math::BaseArith qw( :all );
encode_base( $value, \@base );
decode_base( \@representation, \@base );
my @yd_ft_in = (0, 3, 12);
# convert 175 inches to 4 yards 2 feet 7 inches
encode_base( 175, \@yd_ft_in )
# convert 4 yards 2 feet 7 inches to 175 inches
decode_base( [4, 2, 7], \@yd_ft_in )
DESCRIPTION
The inspiration for this module is a pair of functions in the APL
programming language called encode (a.k.a. "represent" or "antibase)"
and decode (a.k.a. base). Their principal use is to convert numbers from
one number base to another. Mixed number bases are permitted.
In this perl implementation, the representation of a number in a
particular number base consists of a list reference whose elements are
the digit values in that base. For example, the decimal number 31 would
be expressed in binary as a list of five ones with any number of leading
zeros: [0, 0, 0, 1, 1, 1, 1, 1]. The same number expressed as three
hexadecimal (base 16) digits would be [0, 1, 15], while in base 10 it
would be [0, 3, 1]. Fifty-one inches would be expressed in yards, feet,
inches as [1, 1, 3], an example of a mixed number base.
FUNCTIONS
In the following description of encode_base and decode_base, Q will mean
an abstract value or quantity, R will be its representation and B will
define the number base. Q will be a perl scalar; R and B are perl lists.
The values in R correspond to the radix values in B.
In the examples below, assume the function output is being printed by:
sub echo { print '=> ', join ', ', @_ }
encode_base
Encode_base is used to represent a number in one or more number bases.
The first argument is the number to be converted, and the second
argument defines the base (or bases) to be used for the representation.
Consider first the representation of a scalar in a single uniform number
base:
encode_base( 2, [2, 2, 2, 2] )
=> 0 0 1 0
encode_base( 5, [2, 2, 2, 2] )
=> 0 1 0 1
encode_base( 13, [2, 2, 2, 2] )
=> 1 1 0 1
encode_base( 62, [16, 16, 16] )
=> 0 3 14
The second argument is called the base list. The length of the base list
determines the number of digits in the representation of the first
argument. No error occurs if the length is insufficient to give a proper
representation of the number. Exploring this situation will suggest
other uses of encode_base, and may clarify the use of encode_base with
mixed number bases.
# The representation of 75 in base 4
encode_base( 75, [4, 4, 4, 4] )
=> 1 0 2 3
# At least four digits are needed for the full representation
encode_base( 75, [4, 4, 4] )
=> 0 2 3
# If fewer elements are in the second argument,
# leading digits do not appear in the representation.
encode_base( 75, [4, 4] )
=> 2 3
# If the second argument is a one-element list reference, encode_base
# is identical to modulus (%)
encode_base( 75, [4] )
=> 3
encode_base( 76, [4] )
=> 0
# The expression encode_base( Q, [0] ) always yields Q as the result
encode_base ( 75, [0] )
=> 75
# This usage returns quotient and remainder
encode_base( 75, [0, 4] )
=> 18 3
# The first quotient (18) is again divided by 4,
# yielding a second quotient and remainder
encode_base( 75, [0, 4, 4] )
=> 4 2 3
# The process is repeated again. Since the last quotient
# is less than 4, the result is the same as encode_base(75,[4,4,4,4])
encode_base( 75, [0, 4, 4, 4] )
=> 1 0 2 3
Now consider a mixed number base: convert 175 inches into yards, feet,
inches.
# 175 inches is 14 feet, 7 inches (quotient and remainder).
encode_base( 175, [0, 12] )
=> 14 7
# 14 feet is 4 yards, 2 feet,
encode_base( 14, [0, 3] )
=> 4 2
# so 175 inches is 4 yards, 2 feet, 7 inches.
encode_base( 175, [0, 3, 12] )
=> 4 2 7
decode_base
decode_base is used to determine the value of the representation of a
quantity in some number base. If R is a list representation (perhaps
produced by the encode_base function described above) of some quantity Q
in a number base defined by the radix list B (i.e., "@R =
encode_base($Q,@B)", then the expression "decode_base(@R,@B)" yields $Q:
decode_base( [0, 0, 1, 0], [2, 2, 2, 2] )
=> 2
decode_base( [0, 1, 0, 1], [2, 2, 2, 2] )
=> 5
decode_base( [0, 3, 14], [16, 16, 16]
=> 62
The length of the representation list must be less than or equal to that
of the base list.
decode_base( [1, 1, 1, 1], [2, 2, 2, 2] )
=> 15
decode_base( [1, 1, 1, 1], [2] )
=> 15
decode_base( [1], [2, 2, 2, 2] )
=> 15
decode_base( [1, 1, 1, 1], [2, 2, 2] )
=> (void)
raises a LENGTH ERROR
As with the encode_base function, mixed number bases can be used:
# Convert 4 yards, 2 feet, 7 inches to inches.
decode_base( [4, 2, 7], [0, 3, 12] )
=> 175
# Convert 2 days, 3 hours, 5 minutes, and 27 seconds to seconds
decode_base( [2, 3, 5, 27], [0, 24, 60, 60] )
=> 183927
# or to minutes.
decode_base( [2, 3, 5, 27], [0, 24, 60, 60] ) / 60
=> 3065.45
The first element of the radix list (second argument) is not used; it is
required only to make the lengths match and so can be any value.
DEPRECATED FUNCTIONS
encode
decode
Synonmous with encode_base/decode_base. Imported by default. See
COMPATIBILITY for details.
COMPATIBILITY
When this module was originally released on CPAN in 2002, it exported
the functions encode and decode by default. These function names,
however, are fairly common and so have a high probability of colliding
in the global namespace with those from other modules. As of version
1.02, the functions were renamed encode_base and decode_base in order to
better distinguish them.
For upward compatibility, encode/decode are provided as aliases for
encode_base/decode_base and are still exported by default so scripts
that include the module by:
use Math::BaseArith;
will continue to work unchanged. See the EXPORT section for the
preferred way to include the module from version 1.02 ownward.
Note the the keyword :old can be used to specify the old function names
(encode/decode). The most likely use of this is to exclude them from the
namespace so you can then include just one of them. For example, to get
decode without encode you can do this:
use Math::BaseArith qw( !:old decode );
But, rather than this approach, consider altering your code to use the
new and preferred function names.
EXPORT
As of version 1.02 and above, the preferred way to include this module
is by using :all, or specifying you want either encode_base or
decode_base:
use Math::BaseArith ':all';
or
use Math::BaseArith 'encode_base';
or
use Math::BaseArith 'decode_base';
Do NOT include it without parameters, as that will automatically import
the old function names encode/decode.
DEBUGGING
Set the global variable $Math::BaseArith::DEBUG to print debugging
information to STDERR.
If set to 1, function names and parameters are printed.
If set to 2, intermediate results are also printed.
LIMITATIONS
The APL encode function allows both arguments to be a list, in which
case the function evaluates in dot-product fashion, generating a matrix
whose columns are the representation vectors for each value in the value
list; i.e. a call such as encode_base([15,31,32,33,75],[4,4,4,4]) would
generate the following matrix;
0 0 0 0 1
0 1 2 2 0
3 3 0 0 2
3 3 0 1 3
This version of encode_base supports only a scalar value as the first
argument.
The APL version of decode support non-integer values. This version
doesn't.
SEE ALSO
AUTHOR
PUCKERING, Gary Puckering
BUGS
Please report any bugs or feature requests to "bug-math-basearith at
rt.cpan.org", or through the web interface at
. I will
be notified, and then you'll automatically be notified of progress on
your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Math::BaseArith
You can also look for information at:
* RT: CPAN's request tracker (report bugs here)
* CPAN Ratings
* Search CPAN
ACKNOWLEDGEMENTS
Kenneth E. Iverson, inventor of APL and author of "A Programming
Language", John Wiley & Sons, 1962
COPYRIGHT AND LICENSE
Copyright (c) 2002, Gary Puckering. All rights reserved.
This module is free software; you can redistribute it and/or modify it
under the same terms as Perl 5. For more details, see the full text of
the licenses in the directory LICENSES. This program is distributed in
the hope that it will be useful, but without any warranty; without even
the implied warranty of merchantability or fitness for a particular
purpose.