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   60481 use 5.006;
  5         15  
4 5     5   23 use strict;
  5         8  
  5         98  
5 5     5   20 use warnings;
  5         6  
  5         110  
6 5     5   2238 use integer;
  5         60  
  5         20  
7 5     5   126 use Carp;
  5         10  
  5         2915  
8            
9             require Exporter;
10            
11             our $VERSION = '1.04';
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 1058 my ($value, $b_aref) = @_;
50            
51 18 50       38 croak 'Function called in void context' unless defined wantarray;
52            
53 18         23 my @b_list = @{ $b_aref }; # copy the base value list
  18         30  
54 18         21 my @r_list;
55 18         30 my @radix_list = (1);
56            
57 18 50       28 print {*STDERR} "encode_base($value ,[@{ $b_aref }])"
  0         0  
  0         0  
58             if $Math::BaseArith::DEBUG >= 1;
59            
60 18         24 my $r = 0;
61 18         20 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         18 do {
67 51         58 $b *= pop @b_list;
68 51         92 unshift @radix_list, $b;
69             } while @b_list;
70            
71 18         23 my $i = 0;
72 18         34 foreach my $b (@radix_list) {
73 69         86 $i++;
74 69 100       87 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         29 next;
79             }
80 45 100       65 $r = $b ? int($value/$b) : 0;
81 45 0       59 printf {*STDERR} "%10d%10d%10d%10d\n", $b,$value,$r,$b?$value%$b:0 if $Math::BaseArith::DEBUG >= 2;
  0 50       0  
82 45         52 push @r_list, $r;
83 45 100       71 $value %= $b if $b;
84             }
85            
86 18         20 shift @r_list while ( scalar(@r_list) > scalar( @{ $b_aref } ) );
  29         51  
87            
88 18 50       101 return wantarray ? @r_list : \@r_list;
89             }
90            
91             #######################################################################
92            
93             sub decode_base {
94 12     12 1 551 my ($r_aref, $b_aref) = @_;
95            
96 12 50       29 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     15 if ( scalar( @{ $r_aref } ) > scalar( @{ $b_aref } ) &&
  12         16  
  12         28  
100 2         8 scalar( @{ $b_aref} ) != 1 )
101             {
102 1         164 carp 'length error';
103 1         87 return;
104             }
105            
106 11         14 my $value = 0;
107 11         14 my $bb = 1;
108 11         12 my $base = 1;
109 11         13 my $r;
110 11         12 my @b_list = @{ $b_aref }; # copy the base value list
  11         19  
111 11         13 my @r_list = @{ $r_aref }; # copy the representation value list
  11         14  
112            
113 11         12 do {
114 39         51 $r = pop @r_list;
115 39         42 $value += $r * $base;
116 39 50       56 printf {*STDERR} "%10d%10d%10d%10d\n", $r,$b,$base,$value
  0         0  
117             if $Math::BaseArith::DEBUG >= 2;
118 39   66     56 $bb = pop @b_list || $bb;
119 39         65 $base *= $bb;
120             } while @r_list;
121            
122 11         54 return $value;
123             }
124            
125             #######################################################################
126             # For signature compatibility with version < 1.02
127            
128 1     1 1 443 sub encode { encode_base(@_) }
129 1     1 1 4 sub decode { decode_base(@_) }
130            
131             #######################################################################
132            
133             1;
134             __END__