File Coverage

blib/lib/Roman.pm
Criterion Covered Total %
statement 33 35 94.2
branch 14 18 77.7
condition 6 9 66.6
subroutine 6 7 85.7
pod 4 4 100.0
total 63 73 86.3


line stmt bran cond sub pod time code
1             package Roman;
2            
3 2     2   22929 use 5.6.0;
  2         4  
4 2     2   6 use warnings;
  2         2  
  2         63  
5 2     2   6 use strict;
  2         12  
  2         856  
6             our $VERSION='1.10_01';
7            
8             =head1 NAME
9            
10             Roman - Perl module for conversion between Roman and Arabic numerals.
11            
12             =head1 VERSION
13            
14             Version 1.10_01
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 SUPPORT
62            
63             You can find documentation for this module with the perldoc command.
64            
65             perldoc Roman
66            
67             You can also look for information at:
68            
69             =over 4
70            
71             =item * AnnoCPAN: Annotated CPAN documentation
72            
73             L
74            
75             =item * CPAN Ratings
76            
77             L
78            
79             =item * RT: CPAN's request tracker
80            
81             L
82            
83             =item * Search CPAN
84            
85             L
86            
87             =back
88            
89             =head1 AUTHOR
90            
91             OZAWA Sakuro 1995-1997
92             Alexandr Ciornii, C<< >> 2007
93            
94             =head1 COPYRIGHT
95            
96             Copyright (c) 1995 OZAWA Sakuro. All rights reserved. This program
97             is free software; you can redistribute it and/or modify it under the
98             same terms as Perl itself.
99            
100             =cut
101            
102             require Exporter;
103             our @ISA = qw(Exporter);
104             our @EXPORT = qw(isroman arabic Roman roman);
105            
106             our %roman2arabic = qw(I 1 V 5 X 10 L 50 C 100 D 500 M 1000);
107             my %roman_digit = qw(1 IV 10 XL 100 CD 1000 MMMMMM);
108             my @figure = reverse sort keys %roman_digit;
109             #my %roman_digit;
110             $roman_digit{$_} = [split(//, $roman_digit{$_}, 2)] foreach @figure;
111            
112             sub isroman($) {
113 22     22 1 5235 my $arg = shift;
114 22 50       199 $arg ne '' and
115             $arg =~ /^(?: M{0,3})
116             (?: D?C{0,3} | C[DM])
117             (?: L?X{0,3} | X[LC])
118             (?: V?I{0,3} | I[VX])$/ix;
119             }
120            
121             sub arabic($) {
122 11     11 1 13 my $arg = shift;
123 11 50       12 isroman $arg or return undef;
124 11         14 my($last_digit) = 1000;
125 11         9 my($arabic);
126 11         28 foreach (split(//, uc $arg)) {
127 24         25 my($digit) = $roman2arabic{$_};
128 24 100       44 $arabic -= 2 * $last_digit if $last_digit < $digit;
129 24         30 $arabic += ($last_digit = $digit);
130             }
131 11         42 $arabic;
132             }
133            
134             sub Roman($) {
135 11     11 1 13 my $arg = shift;
136 11 50 33     51 0 < $arg and $arg < 4000 or return undef;
137 11         11 my($x, $roman);
138 11         16 foreach (@figure) {
139 44         42 my($digit, $i, $v) = (int($arg / $_), @{$roman_digit{$_}});
  44         55  
140 44 100 100     178 if (1 <= $digit and $digit <= 3) {
    100 66        
    100          
    100          
    50          
141 8         12 $roman .= $i x $digit;
142             } elsif ($digit == 4) {
143 3         4 $roman .= "$i$v";
144             } elsif ($digit == 5) {
145 3         6 $roman .= $v;
146             } elsif (6 <= $digit and $digit <= 8) {
147 1         2 $roman .= $v . $i x ($digit - 5);
148             } elsif ($digit == 9) {
149 0         0 $roman .= "$i$x";
150             }
151 44         38 $arg -= $digit * $_;
152 44         44 $x = $i;
153             }
154 11         36 $roman;
155             }
156            
157             sub roman($) {
158 0     0 1   lc Roman shift;
159             }
160            
161             1; # End of Roman