File Coverage

blib/lib/Math/BaseArith.pm
Criterion Covered Total %
statement 57 57 100.0
branch 17 26 65.3
condition 5 6 83.3
subroutine 7 7 100.0
pod 0 2 0.0
total 86 98 87.7


line stmt bran cond sub pod time code
1             package Math::BaseArith;
2            
3 1     1   6521 use 5.006;
  1         4  
  1         40  
4 1     1   83 use strict;
  1         5  
  1         44  
5 1     1   5 use warnings;
  1         7  
  1         32  
6 1     1   1065 use integer;
  1         10  
  1         5  
7 1     1   30 use Carp;
  1         1  
  1         905  
8            
9             require Exporter;
10            
11             our @ISA = qw(Exporter);
12            
13             our($debug) = 0;
14            
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18            
19             # This allows declaration use Math::BaseArith ':all';
20             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21             # will save memory.
22             our %EXPORT_TAGS = ( 'all' => [ qw(
23             encode
24             decode
25             $Math::BaseArith::debug
26             ) ] );
27            
28             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
29            
30             our @EXPORT = qw(
31             encode
32             decode
33             );
34             our $VERSION = '1.00';
35            
36             #######################################################################
37            
38             sub encode {
39 16 50   16 0 954 croak "Function called in void context" unless defined wantarray;
40            
41 16         27 my $value = shift; # value to be encoded
42 16         21 my $b_listRef = shift; # list of base values
43            
44 16         34 my @b_list = @$b_listRef; # copy the base value list
45 16         20 my @r_list;
46 16         25 my @radix_list = (1);
47            
48 16 50       33 print STDERR "encode($value ,[@$b_listRef])"
49             if $Math::BaseArith::debug >= 1;
50            
51 16         21 my $r = 0;
52 16         17 my $b = 1;
53            
54             # Compute the radix divisors from the base list, and put in reverse order
55             # [1760,3,12] miles/yards/feet/inches becomes [63360,5280,1760]
56             # [2,2,2,2] becomes [16,8,4,2]
57 16         19 do {
58 43         47 $b *= pop @b_list;
59 43         117 unshift @radix_list, $b;
60             } while @b_list;
61            
62 16         20 my $i = 0;
63 16         25 foreach $b (@radix_list) {
64 59         61 $i++;
65 59 100       111 if ($b > $value) {
66 16 50       32 printf STDERR "%10d%10d%10d%10d\n", $b,$value,$r,$value%$b
67             if $Math::BaseArith::debug >= 2;
68 16 100       29 push @r_list, 0 if $i > 1;
69 16         28 next;
70             }
71 43 100       83 my $r = $b ? int($value/$b) : 0;
72 43 0       77 printf STDERR "%10d%10d%10d%10d\n", $b,$value,$r,$b?$value%$b:0 if $Math::BaseArith::debug >= 2;
    50          
73 43         53 push @r_list, $r;
74 43 100       147 $value %= $b if $b;
75             }
76            
77 16         59 shift @r_list while (scalar(@r_list) > scalar(@$b_listRef));
78            
79 16 50       90 return wantarray ? @r_list : \@r_list;
80             }
81            
82             #######################################################################
83            
84             sub decode {
85 10     10 0 591 my $r_listRef = shift; # list of representation values
86 10         12 my $b_listRef = shift; # list of base values
87            
88 10 50       23 print STDERR "decode([@$r_listRef],[@$b_listRef])"
89             if $Math::BaseArith::debug >= 1;
90            
91 10 100 100     34 if ( scalar(@$r_listRef) > scalar(@$b_listRef) &&
92             scalar(@$b_listRef) != 1 )
93             {
94 1         259 carp "length error";
95 1         83 return;
96             }
97            
98 9         9 my $value = 0;
99 9         11 my $b = 1;
100 9         9 my $base = 1;
101 9         8 my $r;
102            
103 9         9 do {
104 31         38 $r = pop @$r_listRef;
105 31         36 $value += $r * $base;
106 31 50       52 printf STDERR "%10d%10d%10d%10d\n", $r,$b,$base,$value
107             if $Math::BaseArith::debug >= 2;
108 31   66     77 $b = pop @$b_listRef || $b;
109 31         68 $base *= $b;
110             } while @$r_listRef;
111 9         38 $value;
112             }
113            
114             1;
115             __END__