| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
############################################################################### |
|
2
|
|
|
|
|
|
|
# Numbers to Words Module for Perl. |
|
3
|
|
|
|
|
|
|
# Copyright (C) 1996-2016, Lester Hightower |
|
4
|
|
|
|
|
|
|
############################################################################### |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package Lingua::EN::Nums2Words; |
|
7
|
|
|
|
|
|
|
require 5.000; |
|
8
|
|
|
|
|
|
|
require Exporter; |
|
9
|
1
|
|
|
1
|
|
326
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
27
|
|
|
10
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
1867
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our @ISA=qw(Exporter); |
|
13
|
|
|
|
|
|
|
our @EXPORT=qw(num2word num2usdollars num2word_ordinal num2word_short_ordinal); |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = "1.16"; |
|
16
|
0
|
|
|
0
|
0
|
0
|
sub Version { $VERSION; } |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
############################################################################### |
|
19
|
|
|
|
|
|
|
# Private File-Global Variables ############################################### |
|
20
|
|
|
|
|
|
|
############################################################################### |
|
21
|
|
|
|
|
|
|
# Initialization Function init_mod_vars() sets up these variables |
|
22
|
|
|
|
|
|
|
my @Classifications; |
|
23
|
|
|
|
|
|
|
my @MD; |
|
24
|
|
|
|
|
|
|
my @Categories; |
|
25
|
|
|
|
|
|
|
my %CardinalToOrdinalMapping; |
|
26
|
|
|
|
|
|
|
my @CardinalToShortOrdinalMapping; |
|
27
|
|
|
|
|
|
|
my $word_case = 'upper'; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# At module load time, initialize our static, file-global variables. |
|
30
|
|
|
|
|
|
|
# We use these file-global variables to increase performance when one |
|
31
|
|
|
|
|
|
|
# needs to compute many iterations for numbers to words. The alternative |
|
32
|
|
|
|
|
|
|
# would be to re-instantiate the never-changing variables over and over. |
|
33
|
|
|
|
|
|
|
&init_mod_vars; |
|
34
|
|
|
|
|
|
|
############################################################################### |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
############################################################################### |
|
37
|
|
|
|
|
|
|
# Public Functions ############################################################ |
|
38
|
|
|
|
|
|
|
############################################################################### |
|
39
|
|
|
|
|
|
|
sub set_case($) { |
|
40
|
2
|
|
|
2
|
0
|
45
|
my $case=lc(shift @_); |
|
41
|
2
|
|
|
|
|
7
|
my @cases=qw(upper lower); |
|
42
|
2
|
50
|
|
|
|
41
|
if (scalar(grep(/^$case$/, @cases)) != 1) { |
|
43
|
0
|
|
|
|
|
0
|
die __PACKAGE__.":set_case() only accepts these optons: " . |
|
44
|
|
|
|
|
|
|
join(", ", @cases) . "\n"; |
|
45
|
|
|
|
|
|
|
} |
|
46
|
2
|
|
|
|
|
9
|
$word_case=$case; |
|
47
|
|
|
|
|
|
|
} |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub case($) { |
|
50
|
148
|
|
|
148
|
0
|
220
|
my $str=shift @_; |
|
51
|
148
|
100
|
|
|
|
262
|
if ($word_case eq 'upper') { |
|
|
|
50
|
|
|
|
|
|
|
52
|
74
|
|
|
|
|
225
|
return uc($str); |
|
53
|
|
|
|
|
|
|
} elsif ($word_case eq 'lower') { |
|
54
|
74
|
|
|
|
|
203
|
return lc($str); |
|
55
|
|
|
|
|
|
|
} else { |
|
56
|
0
|
|
|
|
|
0
|
retrn $str; |
|
57
|
|
|
|
|
|
|
} |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub num2word { |
|
61
|
88
|
|
|
88
|
0
|
648
|
my $Number = shift(@_); |
|
62
|
88
|
|
|
|
|
137
|
return(case(&num2word_internal($Number, 0))); |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub num2usdollars { |
|
66
|
26
|
|
|
26
|
0
|
312
|
my $Number = shift(@_); |
|
67
|
|
|
|
|
|
|
# OK, lets do some parsing of what we were handed to be nice and |
|
68
|
|
|
|
|
|
|
# flexible to the users of this API |
|
69
|
26
|
|
|
|
|
44
|
$Number=~s/^\$//; # Kill leading dollar sign |
|
70
|
|
|
|
|
|
|
# Get the decimal into hundreths |
|
71
|
|
|
|
|
|
|
# NOTE: sprintf(%f) fails on very large decimal numbers, so we use |
|
72
|
|
|
|
|
|
|
# our RoundToTwoDecimalPlaces() instead of a sprintf() call. |
|
73
|
|
|
|
|
|
|
#$Number=sprintf("%0.02f", $Number); |
|
74
|
26
|
|
|
|
|
75
|
$Number = RoundToTwoDecimalPlaces($Number); |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# Get the num2word version |
|
77
|
26
|
|
|
|
|
50
|
my $Final=num2word_internal($Number, 1); |
|
78
|
|
|
|
|
|
|
# Now whack the num2word version into a US dollar version |
|
79
|
26
|
|
|
|
|
38
|
my $dollar_verb='DOLLAR'; |
|
80
|
26
|
50
|
|
|
|
113
|
if (abs(int($Number)) != 1) { $dollar_verb .= 'S'; } |
|
|
26
|
|
|
|
|
39
|
|
|
81
|
26
|
50
|
|
|
|
132
|
if (! ($Final=~s/ AND / $dollar_verb AND /)) { |
|
82
|
0
|
|
|
|
|
0
|
$Final .= ' DOLLAR'; |
|
83
|
0
|
0
|
|
|
|
0
|
if (abs($Number) != 1) { $Final .='S'; } |
|
|
0
|
|
|
|
|
0
|
|
|
84
|
|
|
|
|
|
|
} else { |
|
85
|
26
|
|
|
|
|
179
|
$Final=~s/(HUNDREDTH|TENTH)([S]?)/CENT$2/; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# Return the verbiage to the calling program |
|
89
|
26
|
|
|
|
|
54
|
return(case($Final)); |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub num2word_ordinal { |
|
93
|
26
|
|
|
26
|
0
|
281
|
my $Number = shift(@_); |
|
94
|
26
|
|
|
|
|
35
|
my($CardPartToConvToOrd, $ConvTo); |
|
95
|
|
|
|
|
|
|
# Get the num2word version |
|
96
|
26
|
|
|
|
|
37
|
my $Final=num2word_internal($Number, 0); |
|
97
|
|
|
|
|
|
|
# Now whack the num2word version into a US dollar version |
|
98
|
|
|
|
|
|
|
|
|
99
|
26
|
100
|
|
|
|
99
|
if ($Final=~/ AND /) { |
|
100
|
18
|
100
|
|
|
|
110
|
if ($Final =~ m/[- ]([A-Z]+) AND/) { |
|
101
|
16
|
|
|
|
|
34
|
$CardPartToConvToOrd=$1; |
|
102
|
16
|
50
|
|
|
|
34
|
if (defined($CardinalToOrdinalMapping{$CardPartToConvToOrd})) { |
|
103
|
16
|
|
|
|
|
21
|
$ConvTo=$CardinalToOrdinalMapping{$CardPartToConvToOrd}; |
|
104
|
|
|
|
|
|
|
} else { |
|
105
|
0
|
|
|
|
|
0
|
$ConvTo=''; |
|
106
|
0
|
|
|
|
|
0
|
warn "NumToWords.pm Missing CardinalToOrdinalMapping -> $CardPartToConvToOrd"; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
16
|
|
|
|
|
272
|
$Final =~ s/([- ])$CardPartToConvToOrd AND/$1$ConvTo AND/; |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
} else { |
|
111
|
8
|
50
|
|
|
|
45
|
if ($Final =~ m/([A-Z]+)$/) { |
|
112
|
8
|
|
|
|
|
16
|
$CardPartToConvToOrd=$1; |
|
113
|
8
|
50
|
|
|
|
15
|
if (defined($CardinalToOrdinalMapping{$CardPartToConvToOrd})) { |
|
114
|
8
|
|
|
|
|
13
|
$ConvTo=$CardinalToOrdinalMapping{$CardPartToConvToOrd}; |
|
115
|
|
|
|
|
|
|
} else { |
|
116
|
0
|
|
|
|
|
0
|
$ConvTo=''; |
|
117
|
0
|
|
|
|
|
0
|
warn "NumToWords.pm Missing CardinalToOrdinalMapping -> $CardPartToConvToOrd"; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
8
|
|
|
|
|
97
|
$Final =~ s/$CardPartToConvToOrd$/$ConvTo/; |
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
# Return the verbiage to the calling program |
|
124
|
26
|
|
|
|
|
102
|
return(case($Final)); |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub num2word_short_ordinal { |
|
128
|
8
|
|
|
8
|
0
|
82
|
my $Number = shift(@_); |
|
129
|
8
|
50
|
|
|
|
20
|
if ($Number != int($Number)) { |
|
130
|
0
|
|
|
|
|
0
|
warn "num2word_short_ordinal can only handle integers!\n"; |
|
131
|
0
|
|
|
|
|
0
|
return($Number); |
|
132
|
|
|
|
|
|
|
} |
|
133
|
8
|
|
|
|
|
10
|
$Number=int($Number); |
|
134
|
8
|
|
|
|
|
12
|
my $least_sig_dig = undef; |
|
135
|
8
|
|
|
|
|
9
|
my $least_2_sig_dig = undef; |
|
136
|
8
|
50
|
|
|
|
27
|
if ($Number=~m/([0-9])?([0-9])$/) { |
|
137
|
8
|
|
|
|
|
15
|
$least_sig_dig=$2; |
|
138
|
8
|
50
|
|
|
|
12
|
if (defined($1)) { |
|
139
|
8
|
|
|
|
|
16
|
$least_2_sig_dig=$1.$2; |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
} else { |
|
142
|
0
|
|
|
|
|
0
|
warn "num2word_short_ordinal couldn't find least significant int!\n"; |
|
143
|
0
|
|
|
|
|
0
|
return($Number); |
|
144
|
|
|
|
|
|
|
} |
|
145
|
|
|
|
|
|
|
|
|
146
|
8
|
100
|
66
|
|
|
28
|
if (defined($least_2_sig_dig) && |
|
147
|
|
|
|
|
|
|
defined($CardinalToShortOrdinalMapping[$least_2_sig_dig])) { |
|
148
|
4
|
|
|
|
|
5
|
$Number.=$CardinalToShortOrdinalMapping[$least_2_sig_dig]; |
|
149
|
|
|
|
|
|
|
} else { |
|
150
|
4
|
|
|
|
|
7
|
$Number.=$CardinalToShortOrdinalMapping[$least_sig_dig]; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
8
|
|
|
|
|
15
|
return(case($Number)); |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
############################################################################### |
|
156
|
|
|
|
|
|
|
# Private Functions ########################################################### |
|
157
|
|
|
|
|
|
|
############################################################################### |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub num2word_internal { |
|
160
|
140
|
|
|
140
|
0
|
185
|
my $Number = shift(@_); |
|
161
|
140
|
|
|
|
|
167
|
my $KeepTrailingZeros = shift(@_); |
|
162
|
140
|
|
|
|
|
260
|
my($ClassificationIndex, %Breakdown, $Index); |
|
163
|
140
|
|
|
|
|
0
|
my($NegativeFlag, $Classification); |
|
164
|
140
|
|
|
|
|
215
|
my($Word, $Final, $DecimalVerbiage) = ("", "", ""); |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# Hand the number off to a function to get the verbiage |
|
167
|
|
|
|
|
|
|
# for what appears after the decimal |
|
168
|
140
|
|
|
|
|
208
|
$DecimalVerbiage = &HandleDecimal($Number, $KeepTrailingZeros); |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Determine if the number is negative and if so, |
|
171
|
|
|
|
|
|
|
# remember that fact and then make it positive |
|
172
|
140
|
100
|
66
|
|
|
472
|
if (length($Number) && ($Number < 0)) { |
|
173
|
18
|
|
|
|
|
29
|
$NegativeFlag=1; $Number = $Number * -1; |
|
|
18
|
|
|
|
|
25
|
|
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
# Take only the integer part of the number for the |
|
177
|
|
|
|
|
|
|
# calculation of the integer part verbiage |
|
178
|
|
|
|
|
|
|
# NOTE: Changed to regex 06/08/1998 by LHH because the int() |
|
179
|
|
|
|
|
|
|
# was preventing the code from doing very large numbers |
|
180
|
|
|
|
|
|
|
# by restricting the precision of $Number. |
|
181
|
|
|
|
|
|
|
# $Number = int($Number); |
|
182
|
140
|
100
|
|
|
|
453
|
if ($Number =~ /^([0-9]*)\./) { |
|
183
|
62
|
|
|
|
|
162
|
$Number = $1; |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# Go through each of the @Classifications breaking off each |
|
187
|
|
|
|
|
|
|
# three number pair from right to left corresponding to |
|
188
|
|
|
|
|
|
|
# each of the @Classifications |
|
189
|
140
|
|
|
|
|
160
|
$ClassificationIndex = 0; |
|
190
|
140
|
|
|
|
|
215
|
while (length($Number) > 0) { |
|
191
|
314
|
100
|
|
|
|
477
|
if (length($Number) > 2) { |
|
192
|
220
|
|
|
|
|
401
|
$Breakdown{$Classifications[$ClassificationIndex]} = |
|
193
|
|
|
|
|
|
|
substr($Number, length($Number) - 3); |
|
194
|
220
|
|
|
|
|
304
|
$Number = substr($Number, 0, length($Number) - 3); |
|
195
|
|
|
|
|
|
|
} else { |
|
196
|
94
|
|
|
|
|
229
|
$Breakdown{$Classifications[$ClassificationIndex]} = $Number; |
|
197
|
94
|
|
|
|
|
117
|
$Number = ""; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
314
|
|
|
|
|
584
|
$ClassificationIndex++; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# Go over each of the @Classifications producing the verbiage |
|
203
|
|
|
|
|
|
|
# for each and adding each to the verbiage stack ($Final) |
|
204
|
140
|
|
|
|
|
176
|
$Index=0; |
|
205
|
140
|
|
|
|
|
197
|
foreach $Classification (@Classifications) { |
|
206
|
|
|
|
|
|
|
# If the value of these three digits == 0 then they can be ignored |
|
207
|
3080
|
100
|
100
|
|
|
5519
|
if ( (! defined($Breakdown{$Classification})) || |
|
208
|
2776
|
|
|
|
|
2923
|
($Breakdown{$Classification} < 1) ) { $Index++; next;} |
|
|
2776
|
|
|
|
|
3482
|
|
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Retrieves the $Word for these three digits |
|
211
|
304
|
|
|
|
|
450
|
$Word = &HandleThreeDigit($Breakdown{$Classification}); |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Leaves "$Classifications[0] off of HUNDREDs-TENs-ONEs numbers |
|
214
|
304
|
100
|
|
|
|
490
|
if ($Index > 0) { |
|
215
|
178
|
|
|
|
|
243
|
$Word .= " " . $Classification; |
|
216
|
|
|
|
|
|
|
} |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# Adds this $Word to the $Final and determines if it needs a comma |
|
219
|
304
|
100
|
|
|
|
468
|
if (length($Final) > 0) { |
|
220
|
178
|
|
|
|
|
319
|
$Final = $Word . ", " . $Final; |
|
221
|
|
|
|
|
|
|
} else { |
|
222
|
126
|
|
|
|
|
201
|
$Final = $Word; |
|
223
|
|
|
|
|
|
|
} |
|
224
|
304
|
|
|
|
|
389
|
$Index++; |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# If our $Final verbiage is an empty string then our original number |
|
228
|
|
|
|
|
|
|
# was zero, so make the verbiage reflect that. |
|
229
|
140
|
100
|
|
|
|
255
|
if (length($Final) == 0) { |
|
230
|
14
|
|
|
|
|
17
|
$Final = "ZERO"; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# If we marked the number as negative in the beginning, make the |
|
234
|
|
|
|
|
|
|
# verbiage reflect that by prepending NEGATIVE |
|
235
|
140
|
100
|
|
|
|
187
|
if ($NegativeFlag) { |
|
236
|
18
|
|
|
|
|
40
|
$Final = "NEGATIVE " . $Final; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
# Now append the decimal portion of the verbiage calculated at the |
|
240
|
|
|
|
|
|
|
# beginning if there is any |
|
241
|
140
|
100
|
|
|
|
259
|
if (length($DecimalVerbiage) > 0) { |
|
242
|
62
|
|
|
|
|
106
|
$Final .= " AND " . $DecimalVerbiage; |
|
243
|
|
|
|
|
|
|
} |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# Return the verbiage to the calling program |
|
246
|
140
|
|
|
|
|
355
|
return($Final); |
|
247
|
|
|
|
|
|
|
} |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
# Helper function which handles three digits from the @Classifications |
|
250
|
|
|
|
|
|
|
# level (THOUSANDS, MILLIONS, etc) - Deals with the HUNDREDs |
|
251
|
|
|
|
|
|
|
sub HandleThreeDigit { |
|
252
|
304
|
|
|
304
|
0
|
438
|
my $Number = shift(@_); |
|
253
|
304
|
|
|
|
|
398
|
my($Hundreds, $HundredVerbiage, $TenVerbiage, $Verbiage); |
|
254
|
|
|
|
|
|
|
|
|
255
|
304
|
100
|
|
|
|
461
|
if (length($Number) > 2) { |
|
256
|
220
|
|
|
|
|
274
|
$Hundreds = substr($Number, 0, 1); |
|
257
|
220
|
|
|
|
|
280
|
$HundredVerbiage = &HandleTwoDigit($Hundreds); |
|
258
|
220
|
100
|
|
|
|
408
|
if (length($HundredVerbiage) > 0) { |
|
259
|
200
|
|
|
|
|
248
|
$HundredVerbiage .= " HUNDRED"; |
|
260
|
|
|
|
|
|
|
} |
|
261
|
220
|
|
|
|
|
280
|
$Number = substr($Number, 1); |
|
262
|
|
|
|
|
|
|
} |
|
263
|
304
|
|
|
|
|
400
|
$TenVerbiage = &HandleTwoDigit($Number); |
|
264
|
304
|
100
|
100
|
|
|
727
|
if ( (defined($HundredVerbiage)) && (length($HundredVerbiage) > 0) ) { |
|
265
|
200
|
|
|
|
|
263
|
$Verbiage = $HundredVerbiage; |
|
266
|
200
|
50
|
|
|
|
310
|
if (length($TenVerbiage)) { $Verbiage .= " " . $TenVerbiage; } |
|
|
200
|
|
|
|
|
330
|
|
|
267
|
|
|
|
|
|
|
} else { |
|
268
|
104
|
|
|
|
|
141
|
$Verbiage=$TenVerbiage; |
|
269
|
|
|
|
|
|
|
} |
|
270
|
304
|
|
|
|
|
491
|
return($Verbiage); |
|
271
|
|
|
|
|
|
|
} |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# Helper function which handles two digits (from 99 to 0) |
|
274
|
|
|
|
|
|
|
sub HandleTwoDigit { |
|
275
|
524
|
|
|
524
|
0
|
683
|
my $Number = shift(@_); |
|
276
|
524
|
|
|
|
|
591
|
my($Verbiage, $Tens, $Ones); |
|
277
|
|
|
|
|
|
|
|
|
278
|
524
|
100
|
|
|
|
707
|
if (length($Number) < 2) { |
|
279
|
284
|
|
|
|
|
563
|
return($MD[$Number]); |
|
280
|
|
|
|
|
|
|
} else { |
|
281
|
240
|
100
|
|
|
|
373
|
if ($Number < 20) { |
|
282
|
62
|
|
|
|
|
103
|
return($MD[$Number]); |
|
283
|
|
|
|
|
|
|
} else { |
|
284
|
178
|
|
|
|
|
253
|
$Tens = substr($Number, 0, 1); |
|
285
|
178
|
|
|
|
|
226
|
$Tens = $Tens * 10; |
|
286
|
178
|
|
|
|
|
258
|
$Ones = substr($Number, 1, 1); |
|
287
|
178
|
100
|
|
|
|
270
|
if (length($MD[$Ones]) > 0) { |
|
288
|
168
|
|
|
|
|
281
|
$Verbiage = $MD[$Tens] . "-" . $MD[$Ones]; |
|
289
|
|
|
|
|
|
|
} else { |
|
290
|
10
|
|
|
|
|
14
|
$Verbiage = $MD[$Tens]; |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
} |
|
294
|
178
|
|
|
|
|
294
|
return($Verbiage); |
|
295
|
|
|
|
|
|
|
} |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub HandleDecimal { |
|
298
|
140
|
|
|
140
|
0
|
191
|
my $DecNumber = shift(@_); |
|
299
|
140
|
|
|
|
|
162
|
my $KeepTrailingZeros = shift(@_); |
|
300
|
140
|
|
|
|
|
158
|
my $Verbiage = ""; |
|
301
|
140
|
|
|
|
|
176
|
my $CategoriesIndex = 0; |
|
302
|
140
|
|
|
|
|
155
|
my $CategoryVerbiage = ''; |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# I'm choosing to do this string-wise rather than mathematically |
|
305
|
|
|
|
|
|
|
# because the error in the mathematics can alter the number from |
|
306
|
|
|
|
|
|
|
# exactly what was sent in for high significance numbers |
|
307
|
|
|
|
|
|
|
# NOTE: Changed "if" to regex 06/08/1998 by LHH because the int() |
|
308
|
|
|
|
|
|
|
# was preventing the code from doing very large numbers |
|
309
|
|
|
|
|
|
|
# by restricting the precision of $Number. |
|
310
|
140
|
100
|
|
|
|
376
|
if ( ! ($DecNumber =~ /\./) ) { |
|
311
|
78
|
|
|
|
|
144
|
return(''); |
|
312
|
|
|
|
|
|
|
} else { |
|
313
|
62
|
|
|
|
|
150
|
$DecNumber = substr($DecNumber, rindex($DecNumber, '.') + 1); |
|
314
|
|
|
|
|
|
|
# Trim off any trailing zeros... |
|
315
|
62
|
100
|
|
|
|
111
|
if (! $KeepTrailingZeros) { $DecNumber =~ s/0+$//; } |
|
|
36
|
|
|
|
|
68
|
|
|
316
|
|
|
|
|
|
|
} |
|
317
|
|
|
|
|
|
|
|
|
318
|
62
|
|
|
|
|
78
|
$CategoriesIndex = length($DecNumber); |
|
319
|
62
|
|
|
|
|
93
|
$CategoryVerbiage = $Categories[$CategoriesIndex - 1]; |
|
320
|
62
|
50
|
33
|
|
|
205
|
if (length($DecNumber) && $DecNumber == 1) { |
|
321
|
|
|
|
|
|
|
# if the value of what is after the decimal place is one, then |
|
322
|
|
|
|
|
|
|
# we need to chop the "s" off the end of the $CategoryVerbiage |
|
323
|
|
|
|
|
|
|
# to make is singular |
|
324
|
0
|
|
|
|
|
0
|
chop($CategoryVerbiage); |
|
325
|
|
|
|
|
|
|
} |
|
326
|
62
|
|
|
|
|
96
|
$Verbiage = &num2word($DecNumber) . " " . $CategoryVerbiage; |
|
327
|
62
|
|
|
|
|
137
|
return($Verbiage); |
|
328
|
|
|
|
|
|
|
} |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# NOTE: sprintf(%f) fails on very large decimal numbers, thus the |
|
331
|
|
|
|
|
|
|
# need for RoundToTwoDecimalPlaces(). |
|
332
|
|
|
|
|
|
|
sub RoundToTwoDecimalPlaces($) { |
|
333
|
26
|
|
|
26
|
0
|
36
|
my $Number=shift @_; |
|
334
|
|
|
|
|
|
|
|
|
335
|
26
|
|
|
|
|
72
|
my($Int,$Dec,$UserScrewUp) = split(/\./, $Number, 3); |
|
336
|
26
|
50
|
33
|
|
|
58
|
if (defined($UserScrewUp) && length($UserScrewUp)) { |
|
337
|
0
|
|
|
|
|
0
|
warn "num2usdollars() given invalid value."; } |
|
338
|
26
|
100
|
|
|
|
50
|
if (! length($Int)) { $Int=0; } |
|
|
2
|
|
|
|
|
3
|
|
|
339
|
26
|
100
|
|
|
|
45
|
$Dec = 0 if not defined($Dec); |
|
340
|
26
|
|
|
|
|
169
|
my $DecPart=int(sprintf("%0.3f", "." . $Dec) * 100 + 0.5); |
|
341
|
|
|
|
|
|
|
|
|
342
|
26
|
|
|
|
|
56
|
$Number=$Int . '.' . $DecPart; |
|
343
|
26
|
|
|
|
|
89
|
return $Number; |
|
344
|
|
|
|
|
|
|
} |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
# This function initializes our static, file-global variables. |
|
347
|
|
|
|
|
|
|
sub init_mod_vars { |
|
348
|
1
|
|
|
1
|
0
|
3
|
@Categories = ( |
|
349
|
|
|
|
|
|
|
"TENTHS", |
|
350
|
|
|
|
|
|
|
"HUNDREDTHS", |
|
351
|
|
|
|
|
|
|
"THOUSANDTHS", |
|
352
|
|
|
|
|
|
|
"TEN-THOUSANDTHS", |
|
353
|
|
|
|
|
|
|
"HUNDRED-THOUSANDTHS", |
|
354
|
|
|
|
|
|
|
"MILLIONTHS", |
|
355
|
|
|
|
|
|
|
"TEN-MILLIONTHS", |
|
356
|
|
|
|
|
|
|
"HUNDRED-MILLIONTHS", |
|
357
|
|
|
|
|
|
|
"BILLIONTHS", |
|
358
|
|
|
|
|
|
|
"TEN-BILLIONTHS", |
|
359
|
|
|
|
|
|
|
"HUNDRED-BILLIONTHS", |
|
360
|
|
|
|
|
|
|
"TRILLIONTHS", |
|
361
|
|
|
|
|
|
|
"QUADRILLIONTHS", |
|
362
|
|
|
|
|
|
|
"QUINTILLIONTHS", |
|
363
|
|
|
|
|
|
|
"SEXTILLIONTHS", |
|
364
|
|
|
|
|
|
|
"SEPTILLIONTHS", |
|
365
|
|
|
|
|
|
|
"OCTILLIONTHS", |
|
366
|
|
|
|
|
|
|
"NONILLIONTHS", |
|
367
|
|
|
|
|
|
|
"DECILLIONTHS", |
|
368
|
|
|
|
|
|
|
"UNDECILLIONTHS", |
|
369
|
|
|
|
|
|
|
"DUODECILLIONTHS", |
|
370
|
|
|
|
|
|
|
"TREDECILLIONTHS", |
|
371
|
|
|
|
|
|
|
"QUATTUORDECILLIONTHS", |
|
372
|
|
|
|
|
|
|
"QUINDECILLIONTHS", |
|
373
|
|
|
|
|
|
|
"SEXDECILLIONTHS", |
|
374
|
|
|
|
|
|
|
"SEPTEMDECILLIONTHS", |
|
375
|
|
|
|
|
|
|
"OCTODECILLIONTHS", |
|
376
|
|
|
|
|
|
|
"NOVEMDECILLIONTHS", |
|
377
|
|
|
|
|
|
|
"VIGINTILLIONTHS" |
|
378
|
|
|
|
|
|
|
); |
|
379
|
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
################################################### |
|
381
|
|
|
|
|
|
|
|
|
382
|
1
|
|
|
|
|
2
|
$MD[0] = ""; |
|
383
|
1
|
|
|
|
|
4
|
$MD[1] = "ONE"; |
|
384
|
1
|
|
|
|
|
2
|
$MD[2] = "TWO"; |
|
385
|
1
|
|
|
|
|
1
|
$MD[3] = "THREE"; |
|
386
|
1
|
|
|
|
|
2
|
$MD[4] = "FOUR"; |
|
387
|
1
|
|
|
|
|
2
|
$MD[5] = "FIVE"; |
|
388
|
1
|
|
|
|
|
1
|
$MD[6] = "SIX"; |
|
389
|
1
|
|
|
|
|
1
|
$MD[7] = "SEVEN"; |
|
390
|
1
|
|
|
|
|
2
|
$MD[8] = "EIGHT"; |
|
391
|
1
|
|
|
|
|
4
|
$MD[9] = "NINE"; |
|
392
|
1
|
|
|
|
|
2
|
$MD[10] = "TEN"; |
|
393
|
1
|
|
|
|
|
1
|
$MD[11] = "ELEVEN"; |
|
394
|
1
|
|
|
|
|
3
|
$MD[12] = "TWELVE"; |
|
395
|
1
|
|
|
|
|
1
|
$MD[13] = "THIRTEEN"; |
|
396
|
1
|
|
|
|
|
2
|
$MD[14] = "FOURTEEN"; |
|
397
|
1
|
|
|
|
|
1
|
$MD[15] = "FIFTEEN"; |
|
398
|
1
|
|
|
|
|
2
|
$MD[16] = "SIXTEEN"; |
|
399
|
1
|
|
|
|
|
1
|
$MD[17] = "SEVENTEEN"; |
|
400
|
1
|
|
|
|
|
2
|
$MD[18] = "EIGHTEEN"; |
|
401
|
1
|
|
|
|
|
1
|
$MD[19] = "NINETEEN"; |
|
402
|
1
|
|
|
|
|
2
|
$MD[20] = "TWENTY"; |
|
403
|
1
|
|
|
|
|
1
|
$MD[30] = "THIRTY"; |
|
404
|
1
|
|
|
|
|
2
|
$MD[40] = "FORTY"; |
|
405
|
1
|
|
|
|
|
1
|
$MD[50] = "FIFTY"; |
|
406
|
1
|
|
|
|
|
2
|
$MD[60] = "SIXTY"; |
|
407
|
1
|
|
|
|
|
1
|
$MD[70] = "SEVENTY"; |
|
408
|
1
|
|
|
|
|
2
|
$MD[80] = "EIGHTY"; |
|
409
|
1
|
|
|
|
|
1
|
$MD[90] = "NINETY"; |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
################################################### |
|
412
|
|
|
|
|
|
|
|
|
413
|
1
|
|
|
|
|
3
|
@Classifications = ( |
|
414
|
|
|
|
|
|
|
"HUNDREDs-TENs-ONEs", |
|
415
|
|
|
|
|
|
|
"THOUSAND", |
|
416
|
|
|
|
|
|
|
"MILLION", |
|
417
|
|
|
|
|
|
|
"BILLION", |
|
418
|
|
|
|
|
|
|
"TRILLION", |
|
419
|
|
|
|
|
|
|
"QUADRILLION", |
|
420
|
|
|
|
|
|
|
"QUINTILLION", |
|
421
|
|
|
|
|
|
|
"SEXTILLION", |
|
422
|
|
|
|
|
|
|
"SEPTILLION", |
|
423
|
|
|
|
|
|
|
"OCTILLION", |
|
424
|
|
|
|
|
|
|
"NONILLION", |
|
425
|
|
|
|
|
|
|
"DECILLION", |
|
426
|
|
|
|
|
|
|
"UNDECILLION", |
|
427
|
|
|
|
|
|
|
"DUODECILLION", |
|
428
|
|
|
|
|
|
|
"TREDECILLION", |
|
429
|
|
|
|
|
|
|
"QUATTUORDECILLION", |
|
430
|
|
|
|
|
|
|
"QUINDECILLION", |
|
431
|
|
|
|
|
|
|
"SEXDECILLION", |
|
432
|
|
|
|
|
|
|
"SEPTEMDECILLION", |
|
433
|
|
|
|
|
|
|
"OCTODECILLION", |
|
434
|
|
|
|
|
|
|
"NOVEMDECILLION", |
|
435
|
|
|
|
|
|
|
"VIGINTILLION" |
|
436
|
|
|
|
|
|
|
); |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
################################################### |
|
440
|
|
|
|
|
|
|
|
|
441
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'ZERO'} = "ZEROTH"; |
|
442
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'ONE'} = "FIRST"; |
|
443
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'TWO'} = "SECOND"; |
|
444
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'THREE'} = "THIRD"; |
|
445
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'FOUR'} = "FOURTH"; |
|
446
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'FIVE'} = "FIFTH"; |
|
447
|
1
|
|
|
|
|
11
|
$CardinalToOrdinalMapping{'SIX'} = "SIXTH"; |
|
448
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'SEVEN'} = "SEVENTH"; |
|
449
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'EIGHT'} = "EIGHTH"; |
|
450
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'NINE'} = "NINTH"; |
|
451
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'TEN'} = "TENTH"; |
|
452
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'ELEVEN'} = "ELEVENTH"; |
|
453
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'TWELVE'} = "TWELFTH"; |
|
454
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'THIRTEEN'} = "THIRTEENTH"; |
|
455
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'FOURTEEN'} = "FOURTEENTH"; |
|
456
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'FIFTEEN'} = "FIFTEENTH"; |
|
457
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'SIXTEEN'} = "SIXTEENTH"; |
|
458
|
1
|
|
|
|
|
5
|
$CardinalToOrdinalMapping{'SEVENTEEN'} = "SEVENTEENTH"; |
|
459
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'EIGHTEEN'} = "EIGHTEENTH"; |
|
460
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'NINETEEN'} = "NINETEENTH"; |
|
461
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'TWENTY'} = "TWENTIETH"; |
|
462
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'THIRTY'} = "THIRTIETH"; |
|
463
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'FORTY'} = "FORTIETH"; |
|
464
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'FIFTY'} = "FIFTIETH"; |
|
465
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'SIXTY'} = "SIXTIETH"; |
|
466
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'SEVENTY'} = "SEVENTIETH"; |
|
467
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'EIGHTY'} = "EIGHTIETH"; |
|
468
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'NINETY'} = "NINETIETH"; |
|
469
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'HUNDRED'} = "HUNDREDTH"; |
|
470
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'THOUSAND'} = "THOUSANDTH"; |
|
471
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'MILLION'} = "MILLIONTH"; |
|
472
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'BILLION'} = "BILLIONTH"; |
|
473
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'TRILLION'} = "TRILLIONTH"; |
|
474
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'QUADRILLION'} = "QUADRILLIONTH"; |
|
475
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'QUINTILLION'} = "QUINTILLIONTH"; |
|
476
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'SEXTILLION'} = "SEXTILLIONTH"; |
|
477
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'SEPTILLION'} = "SEPTILLIONTH"; |
|
478
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'OCTILLION'} = "OCTILLIONTH"; |
|
479
|
1
|
|
|
|
|
3
|
$CardinalToOrdinalMapping{'NONILLION'} = "NONILLIONTH"; |
|
480
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'DECILLION'} = "DECILLIONTH"; |
|
481
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'TREDECILLION'} = "TREDECILLIONTH"; |
|
482
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'QUATTUORDECILLION'} = "QUATTUORDECILLIONTH"; |
|
483
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'QUINDECILLION'} = "QUINDECILLIONTH"; |
|
484
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'SEXDECILLION'} = "SEXDECILLIONTH"; |
|
485
|
1
|
|
|
|
|
6
|
$CardinalToOrdinalMapping{'SEPTEMDECILLION'} = "SEPTEMDECILLIONTH"; |
|
486
|
1
|
|
|
|
|
1
|
$CardinalToOrdinalMapping{'OCTODECILLION'} = "OCTODECILLIONTH"; |
|
487
|
1
|
|
|
|
|
2
|
$CardinalToOrdinalMapping{'NOVEMDECILLION'} = "NOVEMDECILLIONTH"; |
|
488
|
1
|
|
|
|
|
6
|
$CardinalToOrdinalMapping{'VIGINTILLION'} = "VIGINTILLIONTH"; |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
################################################### |
|
491
|
1
|
|
|
|
|
2
|
$CardinalToShortOrdinalMapping[0]='th'; |
|
492
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[1]='st'; |
|
493
|
1
|
|
|
|
|
2
|
$CardinalToShortOrdinalMapping[11]='th'; # Special for low teens |
|
494
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[2]='nd'; |
|
495
|
1
|
|
|
|
|
2
|
$CardinalToShortOrdinalMapping[12]='th'; # Special for low teens |
|
496
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[3]='rd'; |
|
497
|
1
|
|
|
|
|
2
|
$CardinalToShortOrdinalMapping[13]='th'; # Special for low teens |
|
498
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[4]='th'; |
|
499
|
1
|
|
|
|
|
2
|
$CardinalToShortOrdinalMapping[5]='th'; |
|
500
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[6]='th'; |
|
501
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[7]='th'; |
|
502
|
1
|
|
|
|
|
1
|
$CardinalToShortOrdinalMapping[8]='th'; |
|
503
|
1
|
|
|
|
|
2
|
$CardinalToShortOrdinalMapping[9]='th'; |
|
504
|
|
|
|
|
|
|
} |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
1; |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
# PERL POD #################################################################### |
|
511
|
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=head1 NAME |
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
Lingua::EN::Nums2Words - generate English verbiage from numerical values |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
use Lingua::EN::Nums2Words; |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
$Number = 42; |
|
521
|
|
|
|
|
|
|
$Verbiage = num2word($Number); |
|
522
|
|
|
|
|
|
|
$Verbiage = num2word_ordinal($Number); |
|
523
|
|
|
|
|
|
|
$Verbiage = num2word_short_ordinal($Number); |
|
524
|
|
|
|
|
|
|
$Verbiage = num2usdollars($Number); |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
This module provides functions that can be used to generate English |
|
529
|
|
|
|
|
|
|
verbiage for numbers. |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
To the best of my knowledge, this code can handle every real value |
|
532
|
|
|
|
|
|
|
from negative infinity to positive infinity. |
|
533
|
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
This module makes verbiage in "short scales" (1,000,000,000 is "one billion" |
|
535
|
|
|
|
|
|
|
rather than "one thousand million"). For details see this Wikipedia article: |
|
536
|
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
L |
|
538
|
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=head1 SUBROUTINES |
|
540
|
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
The following code illustrates use of the four functions in this module: |
|
542
|
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
use Lingua::EN::Nums2Words; |
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
$age = 45; |
|
546
|
|
|
|
|
|
|
print "I am ", num2word($age), " years old.\n"; |
|
547
|
|
|
|
|
|
|
print "I've had my ", num2word_ordinal($age), " birthday.\n"; |
|
548
|
|
|
|
|
|
|
print "I'm in my ", num2word_short_ordinal($age+1), " year.\n"; |
|
549
|
|
|
|
|
|
|
print "Pay me ", num2usdollars($age), ".\n"; |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
This prints out: |
|
552
|
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
I am FORTY-FIVE years old. |
|
554
|
|
|
|
|
|
|
I've had my FORTY-FIFTH birthday. |
|
555
|
|
|
|
|
|
|
I'm in my 46th year. |
|
556
|
|
|
|
|
|
|
Pay me FORTY-FIVE DOLLARS AND ZERO CENTS. |
|
557
|
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
As shown above, the default is to return uppercase words. If you would |
|
559
|
|
|
|
|
|
|
prefer to have lowercase words returned, make this call once, early in |
|
560
|
|
|
|
|
|
|
your program: |
|
561
|
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
Lingua::EN::Nums2Words::set_case('lower'); # Accepts upper|lower |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
565
|
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
Copyright (C) 1996-2016, Lester H. Hightower, Jr. |
|
567
|
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
=head1 LICENSE |
|
569
|
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
As of version 1.13, this software is licensed under the OSI certified |
|
571
|
|
|
|
|
|
|
Artistic License, one of the licenses of Perl itself. |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
L |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=cut |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
############################################################################### |
|
578
|
|
|
|
|
|
|
|