Just for the heck of it...
use strict;
use warnings;
my (@units, @numbers, @teens, @tens, @thousands, @nums, $i);
@units = qw/pound pounds pence pence/;
@nums = qw/zero one two three four five six seven eight nine ten
eleven twelve thirteen fourteen fifteen sixteen seventeen e
+ighteen nineteen/;
@tens = qw/ten twenty thirty forty fifty sixty seventy eighty ninety/;
@thousands = qw/thousand million billion trillion/;
for $i (1..8) {
push @nums, $tens[$i];
push @nums, "$tens[$i]-$nums[$_]" for 1..9;
}
for $i (1..9) {
push @nums, "$nums[$i] hundred";
push @nums, "$nums[$i] hundred $nums[$_]" for 1..99;
}
sub wordnum {
my ($n, $num, $dec, $bunit, $sunit, @num, $out, $i) = $_[0];
($num, $dec) = split /\./, $n;
$bunit = ($num == 1 ? $units[0] : $units[1]);
$sunit = ($dec == 1 ? $units[2] : $units[3]);
$dec = "$bunit and $nums[$dec] $sunit";
return "$nums[0] $dec" if $num == 0;
$out = $dec;
$num -= 0; $num = ' ' . $num while length($num) % 3;
push @num, $1 while $num =~ /(...)/g;
@num = reverse @num;
for ($i = 0; $i <= $#num; $i++) {
next if $num[$i] == 0;
$out = $nums[$num[$i]] . ($i ? " $thousands[$i-1]" : '') . ' '
+ . $out;
}
return $out;
}
for (1..20) {
$_ = (int rand 5000) . '.' . (int rand 100);
print "$_ = " . wordnum($_) . "\n";
}
I imagine there are ways to do various parts of this much prettier. For instance, dividing a number into chunks of three digits starting from the right. But the code is functional. |