File Coverage

blib/lib/Math/BaseCnv.pm
Criterion Covered Total %
statement 87 102 85.2
branch 26 44 59.0
condition 9 26 34.6
subroutine 18 19 94.7
pod 9 12 75.0
total 149 203 73.4


line stmt bran cond sub pod time code
1             # 315J9mLT:Math::BaseCnv.pm by PipStuart to CoNVert between arbitrary number Bases. I'm totally addicted to bass!
2             package Math::BaseCnv;
3 2     2   10653 use strict;use warnings;use utf8;
  2     2   3  
  2     2   42  
  2         6  
  2         1  
  2         61  
  2         470  
  2         8  
  2         9  
4             require Exporter ;
5 2     2   58 use base qw(Exporter);
  2         3  
  2         140  
6 2     2   1669 use Math::BigInt;
  2         29214  
  2         10  
7 2     2   19778 use Memoize;memoize('summ');memoize('fact');memoize('choo');
  2         3270  
  2         147  
8 2     2   9 use Carp; # only export cnv() for 'use Math::BaseCnv;' && all other stuff optionally
  2         3  
  2         3286  
9             our @EXPORT = qw(cnv ) ;
10             our @EXPORT_OK = qw( dec heX HEX b10 b64 b64sort dig diginit summ fact choo) ;
11             our %EXPORT_TAGS = ( 'all' =>[ qw(cnv dec heX HEX b10 b64 b64sort dig diginit summ fact choo) ],
12             'heX' =>[ qw(cnv dec heX HEX ) ],
13             'b64' =>[ qw(cnv b10 b64 b64sort ) ],
14             'dig' =>[ qw( dig diginit ) ],
15             'sfc' =>[ qw( summ fact choo) ] );
16             our $VERSION = '1.12';our $d8VS='G7OMKBCn';
17             my $d2bs='';my %bs2d=();my $nega='';
18             my %digsets = (
19             'usr' => [], # this will be assigned if a dig(\@newd) call is made
20             'bin' => ['0', '1'],
21             'dna' => ['a', 'c', 'g', 't'],
22             'DNA' => ['A', 'C', 'G', 'T'],
23             'oct' => ['0'..'7'],
24             'dec' => ['0'..'9'],
25             'heX' => ['0'..'9', 'a'..'f'],
26             'HEX' => ['0'..'9', 'A'..'F'],
27             'b36' => ['0'..'9', 'a'..'z'],
28             'B36' => ['0'..'9', 'A'..'Z'],
29             'b62' => ['0'..'9', 'a'..'z', 'A'..'Z'],
30             'b64' => ['0'..'9', 'A'..'Z', 'a'..'z', '.', '_'], # month:C:12 day:V:31
31             'm64' => ['A'..'Z', 'a'..'z', '0'..'9', '+', '/'], # 0-63 from MIME::Base64
32             'iru' => ['A'..'Z', 'a'..'z', '0'..'9', '[', ']'], # P10 server-server protocol used by IRCu daemon
33             'url' => ['A'..'Z', 'a'..'z', '0'..'9', '-', '_'], # MIME::Base64::URLSafe which avoids %2B && %2F expansions of '+' && '/' respectively
34             'rgx' => ['A'..'Z', 'a'..'z', '0'..'9', '!', '-'], # ReGular eXpression variant
35             'id0' => ['A'..'Z', 'a'..'z', '0'..'9', '_', '-'], # IDentifier style 0
36             'id1' => ['A'..'Z', 'a'..'z', '0'..'9', '.', '_'], # IDentifier style 1
37             'xnt' => ['A'..'Z', 'a'..'z', '0'..'9', '.', '-'], # XML Name Tokens (Nmtoken)
38             'xid' => ['A'..'Z', 'a'..'z', '0'..'9', '_', ':'], # XML identifiers (Name )
39             'sxl' => ['?', '@', 'A'..'Z', '[','\\', ']', '^', # Sixel Base64 from VT100.Net
40             '_', '`', 'a'..'z', '{', '|', '}', '~'],
41             'b85' => ['0'..'9', 'A'..'Z', 'a'..'z', '!', '#', # RFC 1924 for IPv6 addresses like in Math::Base85
42             '$', '%', '&', '(', ')', '*', '+', '-', ';', '<', '=', '>', '?', '@', '^', '_', '`', '{', '|', '}', '~'],
43             'asc' => [' ', '!', '"', '#', '$', '%', '&', "'", # Base96 7-bit printable 0x20 (space) - 0x7F (tilde ~) 'ascii' from Math::Base::Convert
44             '(', ')', '*', '+', ',', '-', '.', '/', '0'..'9', ':', ';', '<', '=', '>', '?', '@', 'A'..'Z', '[','\\',
45             ']', '^', '_', '`', 'a'..'z', '{', '|', '}', '~'],
46             'b96' => ['0'..'9', 'A'..'Z', 'a'..'z', '.', '_', # Base96 but starting with b64 characters
47             ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '/', ':', ';', '<', '=', '>', '?',
48             '@', '[','\\', ']', '^', '`', '{', '|', '}', '~'],);
49 13     13 0 34 sub bs2init { %bs2d=();for(my $i = 0; $i < @{ $digsets{$d2bs} }; $i++){$bs2d{${ $digsets{$d2bs} }[$i]} = $i;}} # build hash of digit chars => array indices
  13         18  
  293         170  
  293         950  
  306         375  
50 3     3 1 120 sub diginit { $d2bs='b64';bs2init(); } # reset digit character list to initial default and initialize base to digit hash mapping
  3         5  
51             sub dig { # assign a new digit character list
52 12 100   12 1 2339 return( @{ $digsets{$d2bs} } ) unless(@_);
  2         5  
53 10 100       23 if(ref $_[0]) { $d2bs = 'usr'; $digsets{$d2bs} = [ @{ shift() } ]; }
  4         5  
  4         4  
  4         10  
54 6 50       7 else { my $setn = shift(); return(-1) unless(exists $digsets{$setn}); $d2bs = $setn; }
  6         10  
  6         6  
55 10 50       9 diginit() unless(@{ $digsets{$d2bs} });
  10         20  
56 10         14 bs2init(); }
57             sub cnv__10 { # convert from some number base to decimal fast
58 11   50 11 0 19 my $t = shift || '0'; my $s = shift || 64; my $n = Math::BigInt->new();
  11   50     16  
  11         25  
59 11 100       250 $nega = ''; $nega = '-' if($t =~ s/^-//);
  11         22  
60 11 50       34 for(split(//, $t)) { return(-1) unless(exists $bs2d{$_}); }
  69         104  
61 11         25 while(length($t)) { $n += $bs2d{substr($t,0,1,'')}; $n *= $s; }
  69         3779  
  69         4733  
62 11         678 return($nega . int($n / $s)); }
63             sub cnv10__ { # convert from decimal to some number base fast
64 12   50 12 0 39 my $n = Math::BigInt->new(shift || '0'); my $s = shift || 64; my $t = '';
  12   50     267  
  12         11  
65 12 50       10 return(-1) if($s > @{ $digsets{$d2bs} });
  12         18  
66 12 100       9 $nega = ''; $nega = '-' if($n =~ s/^-//);
  12         24  
67 12         196 while($n) { $t = $digsets{$d2bs}->[($n % $s)] . $t; $n = int($n / $s); }
  48         3528  
  48         3739  
68 12 50       1026 if(length($t)) { $t = $nega . $t; }
  12         15  
69 0         0 else { $t = $digsets{$d2bs}->[0]; }
70 12         28 return($t); }
71 2     2 1 5 sub dec { return(cnv__10(uc(shift), 16)); } # shortcut for hexadecimal -> decimal
72 4     4 1 7 sub HEX { return(cnv10__( shift, 16)); } # shortcut for decimal -> HEXADECIMAL
73 4     4 1 14 sub heX { return(lc(HEX(@_))); } # same as above but lowercase
74 4     4 1 120 sub b10 { return(cnv__10( shift, 64)); } # shortcut for base64 -> decimal
75 4     4 1 649 sub b64 { return(cnv10__( shift, 64)); } # shortcut for decimal -> base64
76 0     0 1 0 sub b64sort { return( map { b64($_) } sort { $a <=> $b } map { b10($_) } @_ ); }
  0         0  
  0         0  
  0         0  
77             sub cnv { # CoNVert between any number bases
78 9 50 33 9 1 234 my $numb = shift; return(-1) unless(defined($numb) && length($numb));
  9         35  
79 9         9 my $fbas = shift; my $tbas = shift; my $rslt = ''; my $temp = 0;
  9         5  
  9         6  
  9         8  
80 9 50       19 return($digsets{$d2bs}->[0]) if($numb =~ /^-?0+$/); # lots of (negative?) zeros is just zero
81 9 100       26 if(!defined($tbas)) { # makeup reasonable values for missing params
82 4 50       6 if(!defined($fbas)) { $fbas = 10; $tbas = 16;
  0         0  
  0         0  
83 0 0 0     0 if ($numb =~ /^0x/i || ($numb =~ /[A-F]/i && $numb =~ /^[0-9A-F]+$/i )) { $fbas = 16; $tbas = 10; }
  0 0 0     0  
  0 0 0     0  
84 0         0 elsif($numb =~ /[G-Z._]/i && $numb =~ /^[0-9A-Z._]+$/i) { $fbas = 64; $tbas = 10; }
  0         0  
85 0         0 elsif($numb =~ /\D/) { print "!*EROR*! Can't determine reasonable FromBase && ToBase from number:$numb!\n"; }
86 4         5 } else { $tbas = $fbas; $fbas = 10; }
  4         4  
87             }
88 9 50       19 $fbas = 16 if($fbas =~ /\D/); $tbas = 10 if($tbas =~ /\D/);
  9 50       14  
89 9 50       14 if($fbas == 16) { $numb =~ s/^0x//i; $numb = uc($numb); }
  0         0  
  0         0  
90 9 50 33     26 return(-1) if($fbas < 2 || $tbas < 2); # invalid base error
91 9 100 100     29 $numb = cnv__10($numb, $fbas) if($numb =~ /\D/ || $fbas != 10);
92 9 100       551 $numb = cnv10__($numb, $tbas) if( $tbas != 10);
93 9         19 return($numb);
94             }
95             sub summ { # simple function to calculate summation down to 1
96             my $summ = shift; return(0) unless(defined($summ) && $summ && ($summ > 0)); my $answ = Math::BigInt->new($summ);while(--$summ){$answ +=$summ;} return($answ);
97             }
98             sub fact { # simple function to calculate factorials
99             my $fact = shift; return(0) unless(defined($fact) && $fact && ($fact > 0)); my $answ = Math::BigInt->new($fact);while(--$fact){$answ *=$fact;} return($answ);
100             }
101             sub choo { # simple function to calculate n choose m (i.e., (n! / (m! * (n - m)!)))
102             my $ennn = Math::BigInt->new(shift); my $emmm = Math::BigInt->new(shift);
103             return(0) unless(defined($ennn) && defined($emmm) && $ennn && $emmm && ($ennn != $emmm));
104             ($ennn, $emmm) = ($emmm, $ennn) if($ennn < $emmm); my $diff = Math::BigInt->new($ennn - $emmm); my $answ = Math::BigInt->new(fact($ennn));
105             my $mfct = Math::BigInt->new( fact( $emmm));my $dfct = Math::BigInt->new(fact($diff));
106             $mfct *= $dfct; return(0) unless($mfct);
107             $answ /= $mfct; return($answ);
108             }
109             diginit(); # initialize the Dflt digit set whenever BaseCnv is used
110             8;
111              
112             =encoding utf8
113              
114             =head1 NAME
115              
116             Math::BaseCnv - basic functions to CoNVert between number Bases
117              
118             =head1 VERSION
119              
120             This documentation refers to version 1.12 of Math::BaseCnv, which was released on Sun Jul 24 20:11:12:49 -0500 2016.
121              
122             =head1 SYNOPSIS
123              
124             #!/usr/bin/perl
125             use strict;use warnings;use utf8;use v5.10;use Math::BaseCnv;
126              
127             # CoNVert 63 from base-10 (decimal) to base- 2 (binary )
128             my $binary__63 = cnv( 63 , 10, 2 );
129             # CoNVert 111111 from base- 2 (binary ) to base-16 (HEX )
130             my $HEX_____63 = cnv( 111111 , 2, 16 );
131             # CoNVert 3F from base-16 (HEX ) to base-10 (decimal)
132             my $decimal_63 = cnv( '3F', 16, 10 );
133             say "63 dec->bin $binary__63 bin->HEX $HEX_____63 HEX->dec $decimal_63";
134              
135             =head1 DESCRIPTION
136              
137             BaseCnv provides a few simple functions for converting between arbitrary number bases. It is as fast as I currently know how to make it (of course
138             relying only on the lovely Perl). If you would rather utilize an object syntax for number-base conversion, please see Ken Williams'
139             fine L module.
140              
141             =head1 PURPOSE
142              
143             The reason I created BaseCnv was that I needed a simple way to convert quickly between the 3 number bases I use most (10, 16, and 64). It turned out
144             that it was trivial to handle any arbitrary number base that is represented as characters. High-bit ASCII has proven somewhat problemmatic but at least
145             BaseCnv can simply and reliably convert between any possible base between 2 and 64 (or 96). I'm happy with it and employ b64() in places I probably
146             shouldn't now.
147              
148             =head1 USAGE
149              
150             =head2 cnv($numb[,$from[,$tobs]])
151              
152             CoNVert the number contained in $numb from its current number base ($from) into the result number base ($tobs).
153              
154             B
155              
156             If $numb only contains valid decimal (base 10) digits, it will be converted to HEXADECIMAL (base 16).
157              
158             If $numb only contains valid hexadecimal (base 16) digits or begins with '0x', it will be it will be converted to decimal (base 10).
159              
160             B
161              
162             cnv() assumes that $numb is already in decimal format and uses $from as the $tobs.
163              
164             B
165              
166             The normal (and most clear) usage of cnv() is to provide all three parameters where $numb is converted from $from base to $tobs.
167              
168             cnv() is the only function that is exported from a normal 'use Math::BaseCnv;' command. The other functions below can be imported to local namespaces
169             explicitly or with the following tags:
170              
171             :all - every function described here
172             :heX - only cnv(), dec(), heX(), and HEX()
173             :b64 - only cnv(), b10(), b64(), and b64sort()
174             :dig - only dig() and diginit()
175             :sfc - only summ(), fact(), and choo()
176              
177             =head2 b10($b64n)
178              
179             A shortcut to convert the number given as a parameter ($b64n) from base 64 to decimal (base 10).
180              
181             =head2 b64($b10n)
182              
183             A shortcut to convert the number given as a parameter ($b10n) from decimal (base 10) to base 64.
184              
185             =head2 b64sort(@b64s)
186              
187             A way to sort b64 strings as though they were decimal numbers.
188              
189             =head2 dec($b16n)
190              
191             A shortcut to convert the number given as a parameter ($b16n) from hexadecimal (base 16) to decimal (base 10).
192              
193             =head2 HEX($b10n)
194              
195             A shortcut to convert the number given as a parameter ($b10n) from decimal (base 10) to HEXADECIMAL (base 16) uppercase.
196              
197             =head2 heX($b10n)
198              
199             A shortcut to convert the number given as a parameter ($b10n) from decimal (base 10) to hexadecimal (base 16) lowercase.
200              
201             Please read the L<"NOTES"> regarding heX().
202              
203             =head2 dig(\@newd)
204              
205             Assign the new digit character list to be used in place of the default one. dig() can also alternately accept a string name matching one of the
206             following predefined digit sets:
207              
208             'bin' => ['0', '1'],
209             'dna' => ['a', 'c', 'g', 't'],
210             'DNA' => ['A', 'C', 'G', 'T'],
211             'oct' => ['0'..'7'],
212             'dec' => ['0'..'9'],
213             'heX' => ['0'..'9', 'a'..'f'],
214             'HEX' => ['0'..'9', 'A'..'F'],
215             'b36' => ['0'..'9', 'a'..'z'],
216             'B36' => ['0'..'9', 'A'..'Z'],
217             'b62' => ['0'..'9', 'a'..'z', 'A'..'Z'],
218             'b64' => ['0'..'9', 'A'..'Z', 'a'..'z', '.', '_'], # month:C:12 day:V:31
219             'm64' => ['A'..'Z', 'a'..'z', '0'..'9', '+', '/'], # 0-63 from MIME::Base64
220             'iru' => ['A'..'Z', 'a'..'z', '0'..'9', '[', ']'], # P10 server-server protocol used by IRCu daemon
221             'url' => ['A'..'Z', 'a'..'z', '0'..'9', '-', '_'], # MIME::Base64::URLSafe (avoid %2B %2F expansions)
222             'rgx' => ['A'..'Z', 'a'..'z', '0'..'9', '!', '-'], # ReGular eXpression variant
223             'id0' => ['A'..'Z', 'a'..'z', '0'..'9', '_', '-'], # IDentifier style 0
224             'id1' => ['A'..'Z', 'a'..'z', '0'..'9', '.', '_'], # IDentifier style 1
225             'xnt' => ['A'..'Z', 'a'..'z', '0'..'9', '.', '-'], # XML Name Tokens (Nmtoken)
226             'xid' => ['A'..'Z', 'a'..'z', '0'..'9', '_', ':'], # XML identifiers (Name )
227             'sxl' => ['?', '@', 'A'..'Z', '[','\\', ']', '^', # Sixel Base64 from VT100.Net
228             '_', '`', 'a'..'z', '{', '|', '}', '~'],
229             'b85' => ['0'..'9', 'A'..'Z', 'a'..'z', '!', '#', # RFC 1924 for IPv6 addresses like in Math::Base85
230             '$', '%', '&', '(', ')', '*', '+', '-',
231             ';', '<', '=', '>', '?', '@', '^', '_',
232             '`', '{', '|', '}', '~' ],
233             'asc' => [' ', '!', '"', '#', '$', '%', '&', "'", # Base96 7-bit printable 0x20 (space) - 0x7F
234             '(', ')', '*', '+', ',', '-', '.', '/', # (tilde ~) 'ascii' from Math::Base::Convert
235             '0'..'9', ':', ';', '<', '=', '>', '?',
236             '@', 'A'..'Z', '[','\\', ']', '^', '_',
237             '`', 'a'..'z', '{', '|', '}', '~' ],
238             'b96' => ['0'..'9', 'A'..'Z', 'a'..'z', '.', '_', # Base96 but starting with b64 characters
239             ' ', '!', '"', '#', '$', '%', '&', "'",
240             '(', ')', '*', '+', ',', '-', '/', ':',
241             ';', '<', '=', '>', '?', '@', '[','\\',
242             ']', '^', '`', '{', '|', '}', '~' ],
243              
244             If no \@newd list or digit set name is provided as a parameter, dig() returns the current character list. It's fine to have many more characters
245             in your current digit set than will be used with your conversions (e.g., using dig('b64') works fine for any cnv() call with $from and $tobs params
246             less than or equal to 64).
247              
248             An example of a \@newd parameter for a specified alternate digit set for base 9 conversions is:
249              
250             dig( [ qw( n a c h o z y u m ) ] );
251              
252             =head2 diginit()
253              
254             Resets the used digit list to the initial default order of the predefined digit set: 'b64'. This is simply a shortcut for calling dig('b64') for
255             reinitialization purposes.
256              
257             =head2 summ($numb)
258              
259             A simple function to calculate a memoized BigInt summation of $numb down to 1.
260              
261             =head2 fact($numb)
262              
263             A simple function to calculate a memoized BigInt factorial of $numb.
264              
265             =head2 choo($ennn, $emmm)
266              
267             A simple function to calculate a memoized BigInt function of $ennn choose $emmm.
268              
269             =head1 NOTES
270              
271             The Perl built-in hex() function takes a hex string as a parameter and returns the decimal value (FromBase = 16, ToBase = 10). This notation seems
272             counter-intuitive to me since I prefer to read the code as though a hex() function will turn your parameter into hexadecimal (i.e., I think hex() should
273             hexify your parameter but Perl's built-in does not.). I initially decided to invert the notation for my similar functions, but reconsidered the potential
274             harm possible by introducing exported conflicting opposite behavior into other people's maybe crucial code, so I am falling back on unique casing with heX().
275              
276             My b64() function takes a decimal number as a parameter and returns the base64 equivalent (FromBase = 10, ToBase = 64) and my b10() function takes a base64
277             number (string) and returns the decimal value (FromBase = 64, ToBase = 10). My heX() function opposes Perl's built-in hex() (which is similar to my dec()).
278              
279             Please think of my dec() and heX() functions as meaning decify and heXify. Also the pronunciation of dec() is 'dess' (not 'deck').
280              
281             Error checking is minimal.
282              
283             This module does not handle fractional number inputs because I like using the dot (.) character as a standard base64 digit since it makes for clean filenames.
284              
285             summ(), fact(), and choo() are general Math function utilities which are unrelated to number-base conversion but I didn't feel like making another
286             separate module just for them so they snuck in here.
287              
288             I hope you find Math::BaseCnv useful. TTFN.
289              
290             =head1 CHANGES
291              
292             Revision history for Perl extension Math::BaseCnv:
293              
294             =over 2
295              
296             =item - 1.12 G7OMKBCn Sun Jul 24 20:11:12:49 -0500 2016
297              
298             * added digit set 'b96' as a reordering of 'asc'
299              
300             =item - 1.10 G7OMF3ZT Sun Jul 24 15:03:35:29 -0500 2016
301              
302             * added new digit sets from L
303              
304             * switched all old hex() to distinct new heX() and updated POD to reflect
305              
306             * fixed META license to match POD and resolve issue: L (Thanks again xenoterracide.)
307              
308             * removed PT from VERSION to resolve issue: L (Thanks Alexandr.)
309              
310             =item - 1.8.B59BrZX Mon May 9 11:53:35:33 2011
311              
312             * updated 'url' digit set to URLSafe to resolve L (Thanks xenoterracide.)
313              
314             * updated license copyright years (already had GPLv3)
315              
316             =item - 1.6.A6FGHKE Tue Jun 15 16:17:20:14 2010
317              
318             * bumped minor version number so they'll keep ascending (without PT comprehension)
319              
320             =item - 1.4.A6FAbEb Tue Jun 15 10:37:14:37 2010
321              
322             * added Math::BigInt code for >64-bit number-base conversions
323              
324             * added a bunch more DigitSets: IRCu, URL, RegEx, identifier variants, XML Nmtoken, and XML ID Name
325              
326             =item - 1.4.75O6Pbr Thu May 24 06:25:37:53 2007
327              
328             * added Test::Pod(::Coverage)? tests and PREREQ entries
329              
330             * added b85 for IPv6, generated META.yml (with needed newline before EOF) and updated minor version number
331              
332             =item - 1.2.68J9uJQ Sat Aug 19 09:56:19:26 2006
333              
334             * added b64sort() and put POD at bottom
335              
336             =item - 1.2.59M7mRX Thu Sep 22 07:48:27:33 2005
337              
338             * testing Make as primary and BuildPL backup (needing rename for dot)
339              
340             =item - 1.2.59IBlgw Sun Sep 18 11:47:42:58 2005
341              
342             * testing just using Module::Build instead of MakeMaker
343              
344             * fixed test 12 which was failing on AMD64
345              
346             * added Build.PL to package
347              
348             =item - 1.2.54HK3pB Sun Apr 17 20:03:51:11 2005
349              
350             * removed 128 digit-set since some high-bit characters cause problems on Win32
351              
352             * made bin/cnv only executable to go in EXE_FILES
353              
354             * made Math::BaseCalc a link in POD and updated License
355              
356             =item - 1.2.45UC8fo Sun May 30 12:08:41:50 2004
357              
358             * tidied POD and increased minor version number since CPAN can't read PT in VERSION
359              
360             =item - 1.0.44E9ljP Wed Apr 14 09:47:45:25 2004
361              
362             * added test for divide-by-zero error in choo()
363              
364             * added summ()
365              
366             =item - 1.0.446EIbS Tue Apr 6 14:18:37:28 2004
367              
368             * snuck in fact() and choo()
369              
370             =item - 1.0.42REDir Fri Feb 27 14:13:44:53 2004
371              
372             * changed test.pl to hopefully pass MSWin32-x86-multi-thread
373              
374             =item - 1.0.428LV46 Sun Feb 8 21:31:04:06 2004
375              
376             * broke apart CHANGES to descend chronologically
377              
378             * made dec() auto uppercase param since dec(a) was returning 36 instead of 10
379              
380             =item - 1.0.41M4GMP Thu Jan 22 04:16:22:25 2004
381              
382             * put cnv in bin/ as EXE_FILES
383              
384             =item - 1.0.418BEPc Thu Jan 8 11:14:25:38 2004
385              
386             * testing new e auto-generate MANIFEST(.SKIP)?
387              
388             =item - 1.0.3CNH37s Tue Dec 23 17:03:07:54 2003
389              
390             * updated POD
391              
392             =item - 1.0.3CG3dIx Tue Dec 16 03:39:18:59 2003
393              
394             * normalized base spelling
395              
396             =item - 1.0.3CD1Vdd Sat Dec 13 01:31:39:39 2003
397              
398             * added ABSTRACT section to WriteMakeFile()
399              
400             * changed synopsis example
401              
402             * updated all POD indenting
403              
404             =item - 1.0.3CCA5Mi Fri Dec 12 10:05:22:44 2003
405              
406             * removed indenting from POD NAME field
407              
408             =item - 1.0.3CB7M43 Thu Dec 11 07:22:04:03 2003
409              
410             * updated package to coincide with Time::Fields release
411              
412             =item - 1.0.39B36Lv Thu Sep 11 03:06:21:57 2003
413              
414             * synchronized POD with README documentation using new e utility
415              
416             * templatized package compilation
417              
418             * fixed boundary bugs
419              
420             =item - 1.0.37SLNGN Mon Jul 28 21:23:16:23 2003
421              
422             * first version (and my first Perl module... yay!) put on CPAN
423              
424             =item - 1.0.37JKj3w Sat Jul 19 20:45:03:58 2003
425              
426             * reworked interface from shell utility to package
427              
428             =item - 1.0.3159mLT Sun Jan 5 09:48:21:29 2003
429              
430             * original version
431              
432             =back
433              
434             =head1 TODO
435              
436             =over 2
437              
438             =item - better error checking
439              
440             =item - handle fractions and exponents?
441              
442             =back
443              
444             =head1 INSTALL
445              
446             Please run:
447              
448             `perl -MCPAN -e "install Math::BaseCnv"`
449              
450             or uncompress the package and run:
451              
452             `perl Makefile.PL; make; make test; make install`
453             or if you don't have `make` but Module::Build is installed, try:
454             `perl Build.PL; perl Build; perl Build test; perl Build install`
455              
456             =head1 FILES
457              
458             Math::BaseCnv requires:
459              
460             L to allow Big summ(), fact(), and choo() results
461              
462             L to cache summ(), fact(), and choo() results
463              
464             L to allow errors to croak() from calling sub
465              
466             =head1 LICENSE
467              
468             Most source code should be Free! Code I have lawful authority over is and shall be!
469             Copyright: (c) 2003-2016, Pip Stuart.
470             Copyleft : This software is licensed under the GNU General Public License
471             (version 3 or later). Please consult L
472             for important information about your freedom. This is Free Software: you
473             are free to change and redistribute it. There is NO WARRANTY, to the
474             extent permitted by law. See L for further information.
475              
476             =head1 AUTHOR
477              
478             Pip Stuart
479              
480             =cut