File Coverage

blib/lib/Math/BaseArith.pm
Criterion Covered Total %
statement 65 73 89.0
branch 17 26 65.3
condition 5 6 83.3
subroutine 9 9 100.0
pod 4 4 100.0
total 100 118 84.7


line stmt bran cond sub pod time code
1             package Math::BaseArith;
2              
3 5     5   77117 use 5.006;
  5         16  
4 5     5   24 use strict;
  5         9  
  5         98  
5 5     5   23 use warnings;
  5         10  
  5         143  
6 5     5   2560 use integer;
  5         67  
  5         21  
7 5     5   143 use Carp;
  5         8  
  5         3267  
8              
9             require Exporter;
10              
11             our $VERSION = '1.03'; # VERSION
12              
13             our $DEBUG = 0; # set to 1 to enable debug printing
14              
15             our @ISA = qw(Exporter);
16              
17             # The primary functions of this module were originally named encode/decode.
18             # They were renamed encode_base and # decode_base as of version 1.02 so there
19             # would be less chance of them colliding with other encode/decode functions
20             # from other modules. However, since they were exported by default, it was
21             # necessary to keep them (and their default export) so as not to introduce
22             # an incompatible change. But, they can be turned off using !:old.
23             our @EXPORT = ( qw(encode decode) );
24              
25             # use Math::BaseArith qw(:all !:old) to get encode_base/decode_base
26             # and to keep encode/decode out of the namespace.
27             our %EXPORT_TAGS = (
28             'all' => [
29             'encode_base',
30             'decode_base',
31             ],
32             'old' => [
33             'encode',
34             'decode',
35             ],
36             );
37              
38             # use Math::BaseArith ( qw(!:old encode_base) ) to get just encode_base
39             our @EXPORT_OK = ( qw(
40             encode_base
41             decode_base
42             encode
43             decode
44             ));
45              
46             #######################################################################
47              
48             sub encode_base {
49 18     18 1 1145 my ($value, $b_aref) = @_;
50              
51 18 50       40 croak 'Function called in void context' unless defined wantarray;
52              
53 18         23 my @b_list = @{ $b_aref }; # copy the base value list
  18         31  
54 18         21 my @r_list;
55 18         26 my @radix_list = (1);
56              
57 18 50       32 print {*STDERR} "encode_base($value ,[@{ $b_aref }])"
  0         0  
  0         0  
58             if $Math::BaseArith::DEBUG >= 1;
59              
60 18         20 my $r = 0;
61 18         19 my $b = 1;
62              
63             # Compute the radix divisors from the base list, and put in reverse order
64             # [1760,3,12] miles/yards/feet/inches becomes [63360,5280,1760]
65             # [2,2,2,2] becomes [16,8,4,2]
66 18         20 do {
67 51         59 $b *= pop @b_list;
68 51         91 unshift @radix_list, $b;
69             } while @b_list;
70              
71 18         28 my $i = 0;
72 18         34 foreach my $b (@radix_list) {
73 69         83 $i++;
74 69 100       137 if ($b > $value) {
75 24 50       35 printf {*STDERR} "%10d%10d%10d%10d\n", $b,$value,$r,$value%$b
  0         0  
76             if $Math::BaseArith::DEBUG >= 2;
77 24 100       37 push @r_list, 0 if $i > 1;
78 24         33 next;
79             }
80 45 100       65 $r = $b ? int($value/$b) : 0;
81 45 0       66 printf {*STDERR} "%10d%10d%10d%10d\n", $b,$value,$r,$b?$value%$b:0 if $Math::BaseArith::DEBUG >= 2;
  0 50       0  
82 45         50 push @r_list, $r;
83 45 100       69 $value %= $b if $b;
84             }
85              
86 18         21 shift @r_list while ( scalar(@r_list) > scalar( @{ $b_aref } ) );
  29         49  
87              
88 18 50       104 return wantarray ? @r_list : \@r_list;
89             }
90              
91             #######################################################################
92              
93             sub decode_base {
94 12     12 1 704 my ($r_aref, $b_aref) = @_;
95              
96 12 50       34 print {*STDERR} "decode_base( [ @{$r_aref} ],[ @{ $b_aref} ] )"
  0         0  
  0         0  
  0         0  
97             if $Math::BaseArith::DEBUG >= 1;
98              
99 12 100 100     19 if ( scalar( @{ $r_aref } ) > scalar( @{ $b_aref } ) &&
  12         18  
  12         34  
100 2         9 scalar( @{ $b_aref} ) != 1 )
101             {
102 1         227 carp 'length error';
103 1         115 return;
104             }
105              
106 11         21 my $value = 0;
107 11         16 my $bb = 1;
108 11         16 my $base = 1;
109 11         14 my $r;
110 11         17 my @b_list = @{ $b_aref }; # copy the base value list
  11         20  
111 11         16 my @r_list = @{ $r_aref }; # copy the representation value list
  11         17  
112              
113 11         16 do {
114 39         70 $r = pop @r_list;
115 39         53 $value += $r * $base;
116 39 50       59 printf {*STDERR} "%10d%10d%10d%10d\n", $r,$b,$base,$value
  0         0  
117             if $Math::BaseArith::DEBUG >= 2;
118 39   66     76 $bb = pop @b_list || $bb;
119 39         68 $base *= $bb;
120             } while @r_list;
121              
122 11         65 return $value;
123             }
124              
125             #######################################################################
126             # For signature compatibility with version < 1.02
127              
128 1     1 1 475 sub encode { encode_base(@_) }
129 1     1 1 4 sub decode { decode_base(@_) }
130              
131             #######################################################################
132              
133             1;
134             __END__