File Coverage

lib/Math/BigInt/Named/English.pm
Criterion Covered Total %
statement 57 57 100.0
branch 29 32 90.6
condition 6 6 100.0
subroutine 7 7 100.0
pod 1 1 100.0
total 100 103 97.0


line stmt bran cond sub pod time code
1             #!perl
2              
3             package Math::BigInt::Named::English;
4              
5 3     3   77203 use 5.006001;
  3         20  
6 3     3   18 use strict;
  3         14  
  3         70  
7 3     3   15 use warnings;
  3         5  
  3         115  
8              
9 3     3   451 use Math::BigInt::Named;
  3         15  
  3         31  
10             our @ISA = qw< Math::BigInt::Named >;
11              
12             our $VERSION = '0.06';
13              
14             sub name {
15 50     50 1 33924 my $x = shift;
16 50 50       155 $x = Math::BigInt -> new($x) unless ref($x);
17              
18 50         93 my $class = ref($x);
19              
20 50 50       139 return '' if $x -> is_nan();
21              
22 50         312 my $index = 0;
23              
24 50         105 my $ret = '';
25 50         128 my $y = $x -> copy();
26 50         983 my $rem;
27              
28 50 100       138 if ($y -> sign() eq '-') {
29 1         8 $ret = 'minus ';
30 1         10 $y -> babs();
31             }
32              
33 50 100       435 if ($y < 1000) {
34 45         5300 return $ret . $class -> _triple($y, 1, 0);
35             }
36              
37 5         543 while (!$y -> is_zero()) {
38 10         137 ($y, $rem) = $y -> bdiv(1000);
39 10         2317 $ret = $class -> _triple($rem, 0, $index)
40             . ' ' . $class -> _triple_name($index, $rem) . ' ' . $ret;
41 10         28 $index++;
42             }
43 5         81 $ret =~ s/\s+$//; # trailing spaces
44 5         25 $ret;
45             }
46              
47             my $SMALL = [ qw/
48             zero
49             one
50             two
51             three
52             four
53             five
54             six
55             seven
56             eight
57             nine
58             ten
59             eleven
60             twelve
61             thirteen
62             fourteen
63             fifteen
64             sixteen
65             seventeen
66             eighteen
67             nineteen
68             / ];
69              
70             my $ZEHN = [ qw /
71             ten
72             twenty
73             thirty
74             fourty
75             fifty
76             sixty
77             seventy
78             eighty
79             ninety
80             / ];
81              
82             my $HUNDERT = [ qw /
83             one
84             two
85             three
86             four
87             five
88             six
89             seven
90             eight
91             nine
92             / ];
93              
94             my $TRIPLE = [ qw /
95             mi
96             bi
97             tri
98             quadri
99             penti
100             hexi
101             septi
102             octi
103             / ];
104              
105             sub _triple_name {
106 45     45   2383 my ($self, $index, $number) = @_;
107              
108 45 100 100     209 return '' if $index == 0 || $number -> is_zero();
109 38 100       680 return 'thousand' if $index == 1;
110              
111 32         50 my $postfix = 'llion';
112 32         48 my $plural = 's';
113 32 100       77 if (($index & 1) == 1) {
114 16         28 $postfix = 'lliard';
115             }
116 32 100       73 $postfix .= $plural unless $number -> is_one();
117 32         417 $index -= 2;
118 32         158 $TRIPLE -> [$index >> 1] . $postfix;
119             }
120              
121             sub _triple {
122             # return name of a triple (aka >= 0, and <= 1000)
123             # input: number >= 0, < 1000
124             # only true if triple is the only triple ever ($nr < 1000)
125             # index 0 for last triple, 1 for thousand, 2 for million etc
126 55     55   134 my ($self, $number, $only) = @_;
127              
128 55 100 100     148 return '' if $number -> is_zero() && !$only; # 0 => null, but only for one
129 54 100       811 return $SMALL -> [$number] if $number < scalar @$SMALL; # known name
130              
131 26         2706 my $hundert = $number / 100;
132 26         5803 my $rem = $number % 100;
133 26         4774 my $rc = '';
134 26 100       67 $rc = $HUNDERT -> [$hundert-1] . "hundred" if !$hundert -> is_zero();
135              
136 26         3838 my $concat = '';
137 26 100       68 $concat = 'and' if $rc ne '';
138 26 100       60 return $rc if $rem -> is_zero();
139 17 100       210 return $rc . $concat . $SMALL -> [$rem] if $rem < scalar @$SMALL;
140              
141 14         1431 my $zehn;
142 14         40 ($zehn, $rem) = $rem -> bdiv(10);
143              
144 14         3076 my $last = '';
145 14 100       44 $last = $HUNDERT -> [$rem-1] if !$rem -> is_zero(); # 31, 32..
146 14 50       3089 $last = $ZEHN -> [$zehn-1] . $last if !$zehn -> is_zero(); # 1, 2, 3..
147              
148 14         3150 $rc . $last;
149             }
150              
151             1;
152              
153             __END__