cardinal(12345) returns "twelve thousand, three hundred forty five". ordinal(12345) returns "twelve thousand, three hundred forty fifth". Supports a wide range, though I don't recall offhand if it reaches the maxints. Should be accurate English for every case.

Very naive with regards to "Perl-fu" elegance. Would be interested to see the optimizations that people suggest. I'm not interested in "I can reduce this to 83 characters," I like being able to read the thing later.

@cardinalscore = qw(zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen); @ordinalscore = qw(zeroth first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth nineteenth); @cardinaldecade = qw(zero ten twenty thirty forty fifty sixty seventy eighty ninety hundred); @ordinaldecade = qw(zero tenth twentieth thirtieth fortieth fiftieth sixtieth seventieth eightieth ninetieth hundredth); @cardinalgroup = qw(zero thousand million billion trillion); @cardinalgroupvalue = (1, 1000, 1000000, 1000000000, 1000000000000); sub cardinal { local ($number) = @_; my $name = ''; if ($number < 0) { $name .= "negative "; $number = -$number; } elsif ($number == 0) { return $cardinalscore[0]; } my $comma = 0; foreach $group (reverse (1 .. $#cardinalgroup)) { if ($number >= $cardinalgroupvalue[$group]) { my $multigroup = int($number / $cardinalgroupvalue[$group] +); $name .= cardinal($multigroup) . " " . $cardinalgroup[$gro +up]; $number %= $cardinalgroupvalue[$group]; if ($number > 0) { $name .= ", "; } } } if ($number >= 100) { $name .= cardinal(int($number / 100)) . " " . $cardinaldecade[ +10]; $number %= 100; if ($number > 0) { $name .= " "; } } if ($number >= 20) { $name .= $cardinaldecade[int($number / 10)]; $number %= 10; if ($number > 0) { $name .= "-"; } } if ($number > 0) { $name .= $cardinalscore[$number]; } return $name; } sub ordinal { local ($number) = @_; my $name = ''; if ($number < 0) { $name .= "negative "; $number = -$number; } elsif ($number == 0) { return $ordinalscore[0]; } if ($number >= 100) { $name = cardinal($number - ($number % 100)); if (($number % 1000) > 0 && (($number % 1000) - ($number % 100 +)) == 0) { $name .= ","; } $number %= 100; if ($number > 0) { $name .= " "; } } if ($number == 0) { return $name . "th"; } if ($number >= 20) { my $spare = $number % 10; if ($spare == 0) { $name .= $ordinaldecade[int($number / 10)]; } else { $name .= $cardinaldecade[int($number / 10)] . "-"; } $number = $spare; } if ($number > 0) { $name .= $ordinalscore[$number]; } return $name; } sub testcardinalandordinal { foreach $v (-5, 0, 5, 10, 15, 20, 25, 30, 100, 125, 200, 225, 999, 1000, 1001, 1010, 1011, 1035, 2000, 2345, 1000000, 1001001, 123000789, 123456789) { print "'" . cardinal($v) . "' == $v\n"; print "'" . ordinal($v) . "' == $v th\n"; } } # testcardinalandordinal(); 1;

In reply to cardinal numerals by Speare

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.