Math::Fleximal - Integers with flexible representations. |
Math::Fleximal - Integers with flexible representations.
use Math::Fleximal; my $number = new Math::Fleximal($value, $flex); # Set the value $number = $number->set_value("- $fleck_4$fleck_3"); $number = $number->set_value($another_number);
# Get the object in a familiar form my $string = $number->to_str(); my $integer = $number->base_10(); # Construct more numbers with same flex my $copy = $number->dup(); my $other_number = $number->dup($value); my $absolute_value = $number->abs();
# New representation anyone? my $in_new_base = $number->change_flex($new_flex);
# Arithmetic - can be different flex. Answers have # the flex of $number. $result = $number->add($other_number); $result = $number->mul($other_number); $result = $number->subtr($other_numer); $result = $number->div($other_number);
# And integer-specific arithmetic works $result = $number->gcd($other_number); $result = $number->mod($other_number); my $comparison = $number->cmp($other_number);
This is a package for doing integer arithmetic while using a different base representation than normal. In base n arithmetic you have n symbols which have a representation. I was going to call them ``glyphs'', but being text strings they are not really. On Tye McQueen's whimsical suggestion I settled on the name Math::Fleximal, the set of text representations is called a ``flex'', and the representation of individual digits are the ``flecks''. These names are somewhat unofficial...
This allows you to do basic arithmetic using whatever digits you want, and to convert from one to another.
Like Math::BigInt
it is able to handle very large
numbers, though performance is not very good. (Which
is also like Math::BigInt
, for good performance
you should be using <Bit::Vector>.) Instead use it as
a version of Math::BaseCalc without an upper limit on
the size of numbers. A sample use would be to put an
MD5 hash into a convenient representation:
use Math::Fleximal; use Digest::MD5 qw(md5_hex); my $digest = hex2alpha(md5_hex($data)); # Converts a hex representation of a number into # one that uses more alphanumerics. (ie base 62) sub hex2alpha { Math::Fleximal->new( lc(shift), [0..9, 'a'..'f'] )->change_flex( [0..9,'a'..'z','A'..'Z'] )->to_str(); }
new
This can be used to calculations in bases other than 10 - the base is just the number of flecks in the flex. So you could construct a base 16 number with:
my $base_16 = new Math::Fleximal("4d", [0..9, 'a'..'f']);
If a value is passed it can be an existing Math::Fleximal or (as above) a string that can be parsed with the current flex.
The possible keys to the optional arguments are:
The parsing of a string into flecks is case sensitive. Also possibly ambiguous parses are not handled very well.
dup
set_value
You can either pass the new value an existing instance (which may be in another base) or a string. When passed a string it first strips whitespace. After that it accepts an optional +-, followed by a series of flecks (there must be at least one) for the first to last digits. It will be confused if the leading fleck starts with + or - and no sign is included.
to_str
base_10
change_flex
add
mul
subtr
div
gcd
mod
div
does and returns only the
remainders. In scalar context only the last remainder
is returned. Thus the following returns the
ten-thousands digit:
my $digit = $number->mod(1000, 10);
cmp
one
zero
This will fail if you are trying to work in bases of size more than 30,000 or so.
Only a slight effort is made to resolve potential ambiguities in the parsing of a string into flecks.
Copyright 2000-2001, Ben Tilly (
Math::Fleximal may be copied and distributed on the same terms as Perl itself.
Math::Fleximal - Integers with flexible representations. |