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   10855 use strict;use warnings;use utf8;
  2     2   2  
  2     2   47  
  2         7  
  2         1  
  2         42  
  2         524  
  2         9  
  2         11  
4             require Exporter ;
5 2     2   56 use base qw(Exporter);
  2         3  
  2         164  
6 2     2   1740 use Math::BigInt;
  2         32855  
  2         8  
7 2     2   22157 use Memoize;memoize('summ');memoize('fact');memoize('choo');
  2         3252  
  2         111  
8 2     2   8 use Carp; # only export cnv() for 'use Math::BaseCnv;' && all other stuff optionally
  2         2  
  2         3457  
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.14';our $d8VS='G7UM6iSk';
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 37 sub bs2init { %bs2d=();for(my $i = 0; $i < @{ $digsets{$d2bs} }; $i++){$bs2d{${ $digsets{$d2bs} }[$i]} = $i;}} # build hash of digit chars => array indices
  13         16  
  293         168  
  293         1023  
  306         397  
50 3     3 1 319 sub diginit { $d2bs='b64';bs2init(); } # reset digit character list to initial default and initialize base to digit hash mapping
  3         6  
51             sub dig { # assign a new digit character list
52 12 100   12 1 745 return( @{ $digsets{$d2bs} } ) unless(@_);
  2         4  
53 10 100       14 if(ref $_[0]) { $d2bs = 'usr'; $digsets{$d2bs} = [ @{ shift() } ]; }
  4         6  
  4         3  
  4         9  
54 6 50       5 else { my $setn = shift(); return(-1) unless(exists $digsets{$setn}); $d2bs = $setn; }
  6         12  
  6         7  
55 10 50       12 diginit() unless(@{ $digsets{$d2bs} });
  10         15  
56 10         14 bs2init(); }
57             sub cnv__10 { # convert from some number base to decimal fast
58 11   50 11 0 23 my $t = shift || '0'; my $s = shift || 64; my $n = Math::BigInt->new();
  11   50     14  
  11         27  
59 11 100       262 $nega = ''; $nega = '-' if($t =~ s/^-//);
  11         25  
60 11 50       34 for(split(//, $t)) { return(-1) unless(exists $bs2d{$_}); }
  69         91  
61 11         23 while(length($t)) { $n += $bs2d{substr($t,0,1,'')}; $n *= $s; }
  69         3871  
  69         4660  
62 11         687 return($nega . int($n / $s)); }
63             sub cnv10__ { # convert from decimal to some number base fast
64 12   50 12 0 45 my $n = Math::BigInt->new(shift || '0'); my $s = shift || 64; my $t = '';
  12   50     287  
  12         14  
65 12 50       8 return(-1) if($s > @{ $digsets{$d2bs} });
  12         30  
66 12 100       11 $nega = ''; $nega = '-' if($n =~ s/^-//);
  12         23  
67 12         227 while($n) { $t = $digsets{$d2bs}->[($n % $s)] . $t; $n = int($n / $s); }
  48         3639  
  48         3806  
68 12 50       1157 if(length($t)) { $t = $nega . $t; }
  12         14  
69 0         0 else { $t = $digsets{$d2bs}->[0]; }
70 12         30 return($t); }
71 2     2 1 8 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 13 sub heX { return(lc(HEX(@_))); } # same as above but lowercase
74 4     4 1 126 sub b10 { return(cnv__10( shift, 64)); } # shortcut for base64 -> decimal
75 4     4 1 898 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 40 my $numb = shift; return(-1) unless(defined($numb) && length($numb));
  9         35  
79 9         10 my $fbas = shift; my $tbas = shift; my $rslt = ''; my $temp = 0;
  9         5  
  9         9  
  9         7  
80 9 50       18 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       7 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         3 } else { $tbas = $fbas; $fbas = 10; }
  4         4  
87             }
88 9 50       19 $fbas = 16 if($fbas =~ /\D/); $tbas = 10 if($tbas =~ /\D/);
  9 50       15  
89 9 50       11 if($fbas == 16) { $numb =~ s/^0x//i; $numb = uc($numb); }
  0         0  
  0         0  
90 9 50 33     28 return(-1) if($fbas < 2 || $tbas < 2); # invalid base error
91 9 100 100     28 $numb = cnv__10($numb, $fbas) if($numb =~ /\D/ || $fbas != 10);
92 9 100       560 $numb = cnv10__($numb, $tbas) if( $tbas != 10);
93 9         21 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.14 of Math::BaseCnv, which was released on Sat Jul 30 06:44:28:46 -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. You're probably better off using Michael Robinton's
138             L benchmarked high-performance Perl modules. Another object syntax for number-base conversion is 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.14 G7UM6iSk Sat Jul 30 06:44:28:46 -0500 2016
297              
298             * synchronized README and Changes to updated POD
299              
300             =item - 1.12 G7OMKBCn Sun Jul 24 20:11:12:49 -0500 2016
301              
302             * added digit set 'b96' as a reordering of 'asc'
303              
304             =item - 1.10 G7OMF3ZT Sun Jul 24 15:03:35:29 -0500 2016
305              
306             * added new digit sets from L
307              
308             * switched all old hex() to distinct new heX() and updated POD to reflect
309              
310             * fixed META license to match POD and resolve issue: L (Thanks again xenoterracide.)
311              
312             * removed PT from VERSION to resolve issue: L (Thanks Alexandr.)
313              
314             =item - 1.8.B59BrZX Mon May 9 11:53:35:33 2011
315              
316             * updated 'url' digit set to URLSafe to resolve L (Thanks xenoterracide.)
317              
318             * updated license copyright years (already had GPLv3)
319              
320             =item - 1.6.A6FGHKE Tue Jun 15 16:17:20:14 2010
321              
322             * bumped minor version number so they'll keep ascending (without PT comprehension)
323              
324             =item - 1.4.A6FAbEb Tue Jun 15 10:37:14:37 2010
325              
326             * added Math::BigInt code for >64-bit number-base conversions
327              
328             * added a bunch more DigitSets: IRCu, URL, RegEx, identifier variants, XML Nmtoken, and XML ID Name
329              
330             =item - 1.4.75O6Pbr Thu May 24 06:25:37:53 2007
331              
332             * added Test::Pod(::Coverage)? tests and PREREQ entries
333              
334             * added b85 for IPv6, generated META.yml (with needed newline before EOF) and updated minor version number
335              
336             =item - 1.2.68J9uJQ Sat Aug 19 09:56:19:26 2006
337              
338             * added b64sort() and put POD at bottom
339              
340             =item - 1.2.59M7mRX Thu Sep 22 07:48:27:33 2005
341              
342             * testing Make as primary and BuildPL backup (needing rename for dot)
343              
344             =item - 1.2.59IBlgw Sun Sep 18 11:47:42:58 2005
345              
346             * testing just using Module::Build instead of MakeMaker
347              
348             * fixed test 12 which was failing on AMD64
349              
350             * added Build.PL to package
351              
352             =item - 1.2.54HK3pB Sun Apr 17 20:03:51:11 2005
353              
354             * removed 128 digit-set since some high-bit characters cause problems on Win32
355              
356             * made bin/cnv only executable to go in EXE_FILES
357              
358             * made Math::BaseCalc a link in POD and updated License
359              
360             =item - 1.2.45UC8fo Sun May 30 12:08:41:50 2004
361              
362             * tidied POD and increased minor version number since CPAN can't read PT in VERSION
363              
364             =item - 1.0.44E9ljP Wed Apr 14 09:47:45:25 2004
365              
366             * added test for divide-by-zero error in choo()
367              
368             * added summ()
369              
370             =item - 1.0.446EIbS Tue Apr 6 14:18:37:28 2004
371              
372             * snuck in fact() and choo()
373              
374             =item - 1.0.42REDir Fri Feb 27 14:13:44:53 2004
375              
376             * changed test.pl to hopefully pass MSWin32-x86-multi-thread
377              
378             =item - 1.0.428LV46 Sun Feb 8 21:31:04:06 2004
379              
380             * broke apart CHANGES to descend chronologically
381              
382             * made dec() auto uppercase param since dec(a) was returning 36 instead of 10
383              
384             =item - 1.0.41M4GMP Thu Jan 22 04:16:22:25 2004
385              
386             * put cnv in bin/ as EXE_FILES
387              
388             =item - 1.0.418BEPc Thu Jan 8 11:14:25:38 2004
389              
390             * testing new e auto-generate MANIFEST(.SKIP)?
391              
392             =item - 1.0.3CNH37s Tue Dec 23 17:03:07:54 2003
393              
394             * updated POD
395              
396             =item - 1.0.3CG3dIx Tue Dec 16 03:39:18:59 2003
397              
398             * normalized base spelling
399              
400             =item - 1.0.3CD1Vdd Sat Dec 13 01:31:39:39 2003
401              
402             * added ABSTRACT section to WriteMakeFile()
403              
404             * changed synopsis example
405              
406             * updated all POD indenting
407              
408             =item - 1.0.3CCA5Mi Fri Dec 12 10:05:22:44 2003
409              
410             * removed indenting from POD NAME field
411              
412             =item - 1.0.3CB7M43 Thu Dec 11 07:22:04:03 2003
413              
414             * updated package to coincide with Time::Fields release
415              
416             =item - 1.0.39B36Lv Thu Sep 11 03:06:21:57 2003
417              
418             * synchronized POD with README documentation using new e utility
419              
420             * templatized package compilation
421              
422             * fixed boundary bugs
423              
424             =item - 1.0.37SLNGN Mon Jul 28 21:23:16:23 2003
425              
426             * first version (and my first Perl module... yay!) put on CPAN
427              
428             =item - 1.0.37JKj3w Sat Jul 19 20:45:03:58 2003
429              
430             * reworked interface from shell utility to package
431              
432             =item - 1.0.3159mLT Sun Jan 5 09:48:21:29 2003
433              
434             * original version
435              
436             =back
437              
438             =head1 TODO
439              
440             =over 2
441              
442             =item - better error checking
443              
444             =item - handle fractions and exponents?
445              
446             =back
447              
448             =head1 INSTALL
449              
450             Please run:
451              
452             `perl -MCPAN -e "install Math::BaseCnv"`
453              
454             or uncompress the package and run:
455              
456             `perl Makefile.PL; make; make test; make install`
457             or if you don't have `make` but Module::Build is installed, try:
458             `perl Build.PL; perl Build; perl Build test; perl Build install`
459              
460             =head1 FILES
461              
462             Math::BaseCnv requires:
463              
464             L to allow Big summ(), fact(), and choo() results
465              
466             L to cache summ(), fact(), and choo() results
467              
468             L to allow errors to croak() from calling sub
469              
470             =head1 LICENSE
471              
472             Most source code should be Free! Code I have lawful authority over is and shall be!
473             Copyright: (c) 2003-2016, Pip Stuart.
474             Copyleft : This software is licensed under the GNU General Public License
475             (version 3 or later). Please consult L
476             for important information about your freedom. This is Free Software: you
477             are free to change and redistribute it. There is NO WARRANTY, to the
478             extent permitted by law. See L for further information.
479              
480             =head1 AUTHOR
481              
482             Pip Stuart
483              
484             =cut