File Coverage

blib/lib/Roman.pm
Criterion Covered Total %
statement 37 39 94.8
branch 14 18 77.7
condition 6 9 66.6
subroutine 7 8 87.5
pod 4 4 100.0
total 68 78 87.1


line stmt bran cond sub pod time code
1             package Roman;
2            
3 2     2   39619 use 5.006;
  2         7  
  2         60  
4 2     2   7 use strict;
  2         2  
  2         61  
5 2     2   6 use warnings;
  2         5  
  2         115  
6             our $VERSION='1.24';
7            
8             =head1 NAME
9            
10             Roman - functions for converting between Roman and Arabic numerals
11            
12             =head1 VERSION
13            
14             Version 1.24
15            
16             =cut
17            
18            
19             =head1 SYNOPSIS
20            
21             use Roman;
22            
23             $arabic = arabic($roman) if isroman($roman);
24             $roman = Roman($arabic);
25             $roman = roman($arabic);
26            
27             =head1 DESCRIPTION
28            
29             This package provides some functions which help conversion of numeric
30             notation between Roman and Arabic.
31            
32             =head1 Functions
33            
34             =head2 isroman
35            
36             Tests if argument is valid roman number
37            
38             =head2 arabic
39            
40             roman => arabic
41            
42             =head2 Roman
43            
44             arabic => roman
45            
46             =head2 roman
47            
48             Same as Roman, lowercase
49            
50             =head1 BUGS
51            
52             Domain of valid Roman numerals is limited to less than 4000, since
53             proper Roman digits for the rest are not available in ASCII.
54            
55             Please report any bugs or feature requests to
56             C, or through the web interface at
57             L.
58             I will be notified, and then you'll automatically be notified of progress on
59             your bug as I make changes.
60            
61             =head1 SEE ALSO
62            
63             L - also handles conversion between Arabic and Roman numerals,
64             but can handle a larger range than this module.
65            
66             L -
67             another module for converting between Arabic and Roman numerals.
68            
69             L - handles the same conversion, but also lets
70             you specify upper or lower case.
71            
72             L - make Roman numerals, using Unicode characters.
73            
74             =head1 SUPPORT
75            
76             You can find documentation for this module with the perldoc command.
77            
78             perldoc Roman
79            
80             You can also look for information at:
81            
82             =over 4
83            
84             =item * AnnoCPAN: Annotated CPAN documentation
85            
86             L
87            
88             =item * CPAN Ratings
89            
90             L
91            
92             =item * RT: CPAN's request tracker
93            
94             L
95            
96             =item * Search CPAN
97            
98             L
99            
100             =back
101            
102             =head1 AUTHOR
103            
104             OZAWA Sakuro 1995-1997
105             Alexandr Ciornii, C<< >> 2007
106            
107             =head1 COPYRIGHT
108            
109             Copyright (c) 1995 OZAWA Sakuro. All rights reserved. This program
110             is free software; you can redistribute it and/or modify it under the
111             same terms as Perl itself.
112            
113             =cut
114            
115 2     2   9 use Exporter 'import';
  2         2  
  2         794  
116             #our @ISA = qw(Exporter);
117             our @EXPORT = qw(isroman arabic Roman roman);
118            
119             our %roman2arabic = qw(I 1 V 5 X 10 L 50 C 100 D 500 M 1000);
120             my %roman_digit = qw(1 IV 10 XL 100 CD 1000 MMMMMM);
121             my @figure = reverse sort keys %roman_digit;
122             #my %roman_digit;
123             $roman_digit{$_} = [split(//, $roman_digit{$_}, 2)] foreach @figure;
124            
125             sub isroman($) {
126 22     22 1 5569 my $arg = shift;
127 22 50       312 $arg ne '' and
128             $arg =~ /^(?: M{0,3})
129             (?: D?C{0,3} | C[DM])
130             (?: L?X{0,3} | X[LC])
131             (?: V?I{0,3} | I[VX])$/ix;
132             }
133            
134             sub arabic($) {
135 11     11 1 22 my $arg = shift;
136 11 50       24 isroman $arg or return undef;
137 11         21 my($last_digit) = 1000;
138 11         16 my($arabic);
139 11         47 foreach (split(//, uc $arg)) {
140 24         44 my($digit) = $roman2arabic{$_};
141 24 100       57 $arabic -= 2 * $last_digit if $last_digit < $digit;
142 24         53 $arabic += ($last_digit = $digit);
143             }
144 11         58 $arabic;
145             }
146            
147             sub Roman($) {
148 11     11 1 21 my $arg = shift;
149 11 50 33     65 0 < $arg and $arg < 4000 or return undef;
150 11         18 my($x, $roman);
151 11         23 foreach (@figure) {
152 44         67 my($digit, $i, $v) = (int($arg / $_), @{$roman_digit{$_}});
  44         84  
153 44 100 100     250 if (1 <= $digit and $digit <= 3) {
    100 66        
    100          
    100          
    50          
154 8         20 $roman .= $i x $digit;
155             } elsif ($digit == 4) {
156 3         6 $roman .= "$i$v";
157             } elsif ($digit == 5) {
158 3         6 $roman .= $v;
159             } elsif (6 <= $digit and $digit <= 8) {
160 1         3 $roman .= $v . $i x ($digit - 5);
161             } elsif ($digit == 9) {
162 0         0 $roman .= "$i$x";
163             }
164 44         60 $arg -= $digit * $_;
165 44         77 $x = $i;
166             }
167 11         51 $roman;
168             }
169            
170             sub roman($) {
171 0     0 1   lc Roman shift;
172             }
173            
174             1; # End of Roman