Spelling of ordinal numbers: Difference between revisions

Added FreeBASIC
m (Typo fix)
(Added FreeBASIC)
 
(36 intermediate revisions by 15 users not shown)
Line 17:
 
 
Furthermore, the Americanshort versionscale ofnumbering numberssystem (i.e. 2,000,000,000 is two billion) will be used here.  [[wp:Long (asand opposedshort to the British).scales]]
 
'''2,000,000,000'''   is two billion,   ''not''   two milliard.
Line 39:
*   [[N'th]]
<br><br>
 
=={{header|ALGOL 68}}==
Assumes LONG INT is at least 64 bits, as in e.g., Algol 68G.
<syntaxhighlight lang="algol68">
BEGIN # construct number names from a number #
[]STRING units
= ( "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" );
[]STRING unit prefix
= ( "ten", "twen", "thir", "four", "fif", "six", "seven", "eigh", "nine" );
[]STRING singleth
= ( "first", "second", "third", "fourth", "fifth"
, "sixth", "seventh", "eighth", "nineth"
);
[]STRING power suffix
= ( "thousand", "million", "billion", "trillion", "quadrillion", "quintillion" );
# returns n converted to a number name, n must be 1-99 #
# if final is TRUE, the name will end in st, nd, rd, ... #
PROC two digits = ( INT n, BOOL final )STRING:
IF n < 10 THEN IF final THEN singleth[ n ] ELSE units[ n ] FI
ELIF n = 10 THEN IF final THEN "tenth" ELSE "ten" FI
ELIF n = 11 THEN IF final THEN "eleventh" ELSE "eleven" FI
ELIF n = 12 THEN IF final THEN "twelfth" ELSE "twelve" FI
ELIF n < 20 THEN unit prefix[ n - 10 ]
+ IF final THEN "teenth" ELSE "teen" FI
ELIF n MOD 10 = 0 THEN unit prefix[ n OVER 10 ]
+ IF final THEN "tieth" ELSE "ty" FI
ELSE unit prefix[ n OVER 10 ]
+ "ty "
+ IF final THEN singleth[ n MOD 10 ] ELSE units[ n MOD 10 ] FI
FI # two digits # ;
# returns n converted to a number name, n must be 1-999 #
# if final is TRUE, the name will end in st, nd, rd, ... #
PROC three digits = ( INT n, BOOL final )STRING:
IF n < 100
THEN two digits( n, final )
ELIF STRING hundreds = units[ n OVER 100 ] + " hundred";
INT ending = n MOD 100;
ending = 0
THEN IF final THEN hundreds + "th" ELSE hundreds FI
ELSE hundreds + " and " + two digits( ending, final )
FI # three digits # ;
# returns the "name" of n #
OP NAME = ( LONG INT n )STRING:
IF n < 0 THEN "minus " + NAME - n
ELIF n = 0 THEN "zeroth"
ELSE
# have a positive number to name #
LONG INT v := n;
STRING result := "";
INT power pos := 0;
WHILE v /= 0 DO
BOOL final component = power pos = 0;
INT v999 = SHORTEN ( v MOD 1000 );
IF v999 /= 0 THEN
STRING component := three digits( v999, final component );
IF power pos > 0 THEN
component +:= " " + power suffix[ power pos ];
IF final component THEN component +:= "th" FI
FI;
IF power pos = 0 AND v > 1000 AND v999 < 100 THEN
"and " +=: component
FI;
IF result /= "" THEN component +:= " " FI;
component +=: result
FI;
power pos +:= 1;
v OVERAB 1000
OD;
IF n MOD 1000 = 0 THEN result + "th" ELSE result FI
FI # NAME # ;
# additional operator to handle shorter integers #
OP NAME = ( INT n )STRING: NAME LENG n;
# additional operators to handle integers expressed in floating point #
OP NAME = ( LONG REAL n )STRING: NAME ENTIER n;
OP NAME = ( REAL n )STRING: NAME ENTIER n;
# task test cases #
[]LONG INT t = ( 1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23 456, 8 007 006 005 004 003 );
FOR n FROM LWB t TO UPB t DO
print( ( whole( t[ n ], -16 ), ": ", NAME t[ n ], newline ) )
OD
END
</syntaxhighlight>
{{out}}
<pre>
1: first
2: second
3: third
4: fourth
5: fifth
11: eleventh
65: sixty fifth
100: one hundredth
101: one hundred and first
272: two hundred and seventy second
23456: twenty three thousand four hundred and fifty sixth
8007006005004003: eight quadrillion seven trillion six billion five million four thousand and third
</pre>
 
=={{header|AutoHotkey}}==
Based on [[Number_names#AutoHotkey|Number_names]]
<langsyntaxhighlight AutoHotkeylang="autohotkey">OrdinalNumber(n){
OrdinalNumber := {"one":"first", "two":"second", "three":"third", "five":"fifth", "eight":"eighth", "nine":"ninth", "twelve": "twelfth"}
RegExMatch(n, "\w+$", m)
Line 71 ⟶ 168:
PrettyNumber(n) { ; inserts thousands separators into a number string
Return RegExReplace( RegExReplace(n,"^0+(\d)","$1"), "\G\d+?(?=(\d{3})+(?:\D|$))", "$0,")
}</langsyntaxhighlight>
Example:<langsyntaxhighlight AutoHotkeylang="autohotkey">for i, n in StrSplit("1 2 3 4 5 11 65 100 101 272 23456 8007006005004003", " ")
res .= PrettyNumber(n) "`t" Spell(n) "`t" OrdinalNumber(Spell(n)) "`n"
MsgBox % res
</syntaxhighlight>
</lang>
Outputs:<pre>1 first
2 second
Line 90 ⟶ 187:
 
=={{header|C}}==
{{libheader|GLib}}
<lang c>#include <stdbool.h>
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlibglib.h>
#include <string.h>
 
typedef uint64_t integer;
Line 103 ⟶ 200:
} number_names;
 
const number_names small[] = {
{ "zero", "zeroth" }, { "one", "first" }, { "two", "second" },
{ "three", "third" }, { "four", "fourth" }, { "five", "fifth" },
Line 114 ⟶ 211:
};
 
const number_names tens[] = {
{ "twenty", "twentieth" }, { "thirty", "thirtieth" },
{ "forty", "fortieth" }, { "fifty", "fiftieth" },
Line 127 ⟶ 224:
} named_number;
 
const named_number named_numbers[] = {
{ "hundred", "hundredth", 100 },
{ "thousand", "thousandth", 1000 },
{ "million", "millionth", 1000000 },
{ "billion", "biliionthbillionth", 1000000000 },
{ "trillion", "trillionth", 1000000000000 },
{ "quadrillion", "quadrillionth", 1000000000000000ULL },
Line 145 ⟶ 242:
}
 
const named_number* get_named_number(integer n) {
typedef struct string_builder_tag {
const size_t names_len = sizeof(named_numbers)/sizeof(named_numbers[0]);
size_t size;
for (size_t capacityi = 0; i + 1 < names_len; ++i) {
if (n < named_numbers[i + 1].number)
char* string;
return &named_numbers[i];
} string_builder;
 
void string_builder_append(string_builder* sb, const char* str) {
size_t n = strlen(str);
size_t min_capacity = sb->size + n + 1;
if (sb->capacity < min_capacity) {
size_t new_capacity = sb->capacity * 2;
if (new_capacity < min_capacity)
new_capacity = min_capacity;
char* new_string = realloc(sb->string, new_capacity);
if (new_string == NULL) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
sb->string = new_string;
sb->capacity = new_capacity;
}
return &named_numbers[names_len - 1];
memcpy(sb->string + sb->size, str, n + 1);
sb->size += n;
}
 
void append_number_name(string_builderGString* sbgstr, integer n, bool ordinal) {
if (n < 20)
string_builder_appendg_string_append(sbgstr, get_small_name(&small[n], ordinal));
else if (n < 100) {
if (n % 10 == 0) {
string_builder_appendg_string_append(sbgstr, get_small_name(&tens[n/10 - 2], ordinal));
} else {
string_builder_appendg_string_append(sbgstr, get_small_name(&tens[n/10 - 2], false));
string_builder_appendg_string_append_c(sbgstr, "'-"');
string_builder_appendg_string_append(sbgstr, get_small_name(&small[n % 10], ordinal));
}
} else {
const size_tnamed_number* names_lennum = sizeofget_named_number(named_numbers)/sizeof(named_numbers[0]n);
forinteger (size_t ip = 1num->number; i <= names_len; ++i) {
append_number_name(gstr, n/p, false);
if (i == names_len || n < named_numbers[i].number) {
g_string_append_c(gstr, ' ');
integer p = named_numbers[i-1].number;
if (n % p == 0) append_number_name(sb, n/p, false);{
g_string_append(gstr, string_builder_appendget_big_name(sbnum, " "ordinal));
} if (n % p == 0)else {
string_builder_appendg_string_append(sbgstr, get_big_name(&named_numbers[i-1]num, ordinalfalse));
g_string_append_c(gstr, ' } else {');
append_number_name(gstr, n % p, ordinal);
string_builder_append(sb, get_big_name(&named_numbers[i-1], false));
string_builder_append(sb, " ");
append_number_name(sb, n % p, ordinal);
}
break;
}
}
}
}
 
charGString* number_name(integer n, bool ordinal) {
string_builderGString* result = { 0 }g_string_sized_new(8);
append_number_name(&result, n, ordinal);
return result.string;
}
 
void test_ordinal(integer n) {
charGString* name = number_name(n, true);
printf("%llu: %s\n", n, name->str);
freeg_string_free(name, TRUE);
}
 
Line 234 ⟶ 310:
test_ordinal(8007006005004003LL);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 243 ⟶ 319:
4: fourth
5: fifth
11: tentheleventh
15: fifteenth
21: twenty-first
Line 257 ⟶ 333:
7891233: seven million eight hundred ninety-one thousand two hundred thirty-third
8007006005004003: eight quadrillion seven trillion six billion five million four thousand third
</pre>
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
using System.Collections.Generic;
 
class SpellingOfOrdinalNumbers
{
private static readonly Dictionary<string, string> ordinalMap = new Dictionary<string, string>
{
{"one", "first"},
{"two", "second"},
{"three", "third"},
{"five", "fifth"},
{"eight", "eighth"},
{"nine", "ninth"},
{"twelve", "twelfth"}
};
 
static void Main(string[] args)
{
long[] tests = new long[] { 1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003L };
foreach (long test in tests)
{
Console.WriteLine($"{test} = {ToOrdinal(test)}");
}
}
 
private static string ToOrdinal(long n)
{
string spelling = NumToString(n);
string[] split = spelling.Split(' ');
string last = split[split.Length - 1];
string replace;
if (last.Contains("-"))
{
string[] lastSplit = last.Split('-');
string lastWithDash = lastSplit[1];
string lastReplace;
if (ordinalMap.ContainsKey(lastWithDash))
{
lastReplace = ordinalMap[lastWithDash];
}
else if (lastWithDash.EndsWith("y"))
{
lastReplace = lastWithDash.Substring(0, lastWithDash.Length - 1) + "ieth";
}
else
{
lastReplace = lastWithDash + "th";
}
replace = lastSplit[0] + "-" + lastReplace;
}
else
{
if (ordinalMap.ContainsKey(last))
{
replace = ordinalMap[last];
}
else if (last.EndsWith("y"))
{
replace = last.Substring(0, last.Length - 1) + "ieth";
}
else
{
replace = last + "th";
}
}
split[split.Length - 1] = replace;
return string.Join(" ", split);
}
 
private static readonly string[] nums = new string[]
{
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
};
 
private static readonly string[] tens = new string[] { "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
 
private static string NumToString(long n)
{
return NumToStringHelper(n);
}
 
private static string NumToStringHelper(long n)
{
if (n < 0)
{
return "negative " + NumToStringHelper(-n);
}
if (n <= 19)
{
return nums[n];
}
if (n <= 99)
{
return tens[n / 10] + (n % 10 > 0 ? "-" + NumToStringHelper(n % 10) : "");
}
string label = null;
long factor = 0;
if (n <= 999)
{
label = "hundred";
factor = 100;
}
else if (n <= 999999)
{
label = "thousand";
factor = 1000;
}
else if (n <= 999999999)
{
label = "million";
factor = 1000000;
}
else if (n <= 999999999999L)
{
label = "billion";
factor = 1000000000;
}
else if (n <= 999999999999999L)
{
label = "trillion";
factor = 1000000000000L;
}
else if (n <= 999999999999999999L)
{
label = "quadrillion";
factor = 1000000000000000L;
}
else
{
label = "quintillion";
factor = 1000000000000000000L;
}
return NumToStringHelper(n / factor) + " " + label + (n % factor > 0 ? " " + NumToStringHelper(n % factor) : "");
}
}
</syntaxhighlight>
{{out}}
<pre>
1 = first
2 = second
3 = third
4 = fourth
5 = fifth
11 = eleventh
65 = sixty-fifth
100 = one hundredth
101 = one hundred first
272 = two hundred seventy-second
23456 = twenty-three thousand four hundred fifty-sixth
8007006005004003 = eight quadrillion seven trillion six billion five million four thousand third
 
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <cstdint>
Line 271 ⟶ 504:
};
 
const number_names small[] = {
{ "zero", "zeroth" }, { "one", "first" }, { "two", "second" },
{ "three", "third" }, { "four", "fourth" }, { "five", "fifth" },
Line 282 ⟶ 515:
};
 
const number_names tens[] = {
{ "twenty", "twentieth" }, { "thirty", "thirtieth" },
{ "forty", "fortieth" }, { "fifty", "fiftieth" },
Line 295 ⟶ 528:
};
 
const named_number named_numbers[] = {
{ "hundred", "hundredth", 100 },
{ "thousand", "thousandth", 1000 },
{ "million", "millionth", 1000000 },
{ "billion", "biliionthbillionth", 1000000000 },
{ "trillion", "trillionth", 1000000000000 },
{ "quadrillion", "quadrillionth", 1000000000000000ULL },
Line 311 ⟶ 544:
const char* get_name(const named_number& n, bool ordinal) {
return ordinal ? n.ordinal : n.cardinal;
}
 
const named_number& get_named_number(integer n) {
constexpr size_t names_len = std::size(named_numbers);
for (size_t i = 0; i + 1 < names_len; ++i) {
if (n < named_numbers[i + 1].number)
return named_numbers[i];
}
return named_numbers[names_len - 1];
}
 
Line 326 ⟶ 568:
}
} else {
constexprconst size_tnamed_number& names_lennum = std::sizeget_named_number(named_numbersn);
forinteger (size_t ip = 1num.number; i <= names_len; ++i) {
result = number_name(n/p, false);
if (i == names_len || n < named_numbers[i].number) {
result += " ";
integer p = named_numbers[i-1].number;
if (n % resultp == number_name(n/p,0) false);{
result += "get_name(num, "ordinal);
} if (n % p == 0)else {
result += get_name(named_numbers[i-1]num, ordinalfalse);
result += " } else {";
result += get_namenumber_name(named_numbers[i-1]n % p, falseordinal);
result += " ";
result += number_name(n % p, ordinal);
}
break;
}
}
}
Line 371 ⟶ 608:
test_ordinal(8007006005004003LL);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 380 ⟶ 617:
4: fourth
5: fifth
11: tentheleventh
15: fifteenth
21: twenty-first
Line 397 ⟶ 634:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(def test-cases [1 2 3 4 5 11 65 100 101 272 23456 8007006005004003])
(pprint
(sort (zipmap test-cases (map #(clojure.pprint/cl-format nil "~:R" %) test-cases))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 417 ⟶ 654:
"eight quadrillion, seven trillion, six billion, five million, four thousand, third"])
</pre>
 
=={{header|Common Lisp}}==
Common Lisp's format is able to do this directly. Here's a short function wrapping it and a demonstration.
<syntaxhighlight lang="lisp">(defun ordinal-number (n)
(format nil "~:R" n))
 
#|
CL-USER> (loop for i in '(1 2 3 4 5 11 65 100 101 272 23456 8007006005004003)
do (format t "~a: ~a~%" i (ordinal-number i)))
1: first
2: second
3: third
4: fourth
5: fifth
11: eleventh
65: sixty-fifth
100: one hundredth
101: one hundred first
272: two hundred seventy-second
23456: twenty-three thousand four hundred fifty-sixth
8007006005004003: eight quadrillion seven trillion six billion five million four thousand third
NIL
|#
</syntaxhighlight>
 
=={{header|Factor}}==
Factor's <code>math.text.english</code> vocabulary provides the <code>number>text</code> word for converting numbers to written English. It also provides the <code>ordinal-suffix</code> word for getting the suffix for a given number, such as <tt>th</tt> for <tt>12</tt>. The bulk of this code deals with converting the output of <code>number>text</code> to ordinal format.
<langsyntaxhighlight lang="factor">USING: assocs formatting grouping kernel literals locals math
math.parser math.text.english qw regexp sequences
splitting.extras ;
Line 475 ⟶ 736:
"C{ 123 0 }" C{ 123 0 } print-ordinal-pair ;
MAIN: ordinal-text-demo</langsyntaxhighlight>
{{out}}
<pre>
Line 500 ⟶ 761:
C{ 123 0 } => one hundred twenty-third
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vbnet">Dim Shared small(19) As String*9 => { _
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", _
"nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", _
"sixteen", "seventeen", "eighteen", "nineteen" }
Dim Shared tens(9) As String*7 => { "", "", _
"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }
Dim Shared illions(6) As String*12 => {"", _
" thousand", " million", " billion"," trillion", " quadrillion", " quintillion" }
Dim Shared irregularOrdinals(7, 1) As String*7 = { _
{"one", "first"}, {"two", "second"}, {"three", "third"}, {"five", "fifth"}, _
{"eight", "eighth"}, {"nine", "ninth"}, {"twelve", "twelfth"} }
 
Function spell(n As Integer) As String
Dim As String sx, ix, t = ""
Dim As Integer s, i, p
If n < 0 Then
t = "negative "
n = -n
End If
If n < 20 Then
t &= small(n)
Elseif n < 100 Then
t &= tens(n \ 10)
s = n Mod 10
If s > 0 Then t &= "-" & small(s)
Elseif n < 1000 Then
t &= small(n \ 100) & " hundred"
s = n Mod 100
If s > 0 Then t &= " " & spell(s)
Else
sx = ""
i = 0
While n > 0
p = n Mod 1000
n \= 1000
If p > 0 Then
ix = spell(p) & illions(i)
If sx <> "" Then ix &= " " & sx
sx = ix
End If
i += 1
Wend
t &= sx
End If
Return t
End Function
 
Function sayOrdinal(n As Integer) As String
Dim As String s = spell(n)
Dim As String lastWord = ""
Dim As Integer j, i = Len(s)
While i > 0 And Mid(s, i, 1) <> " " And Mid(s, i, 1) <> "-"
lastWord = Mid(s, i, 1) + lastWord
i -= 1
Wend
For j = 0 To Ubound(irregularOrdinals, 1)
If irregularOrdinals(j, 0) = lastWord Then
Return Left(s, i) + irregularOrdinals(j, 1)
End If
Next j
If Right(s, 1) = "y" Then
Return Left(s, Len(s) - 1) + "ieth"
Else
Return s + "th"
End If
End Function
 
Dim As Integer t(0 To ...) = { 1, 2, 3, 4, 5, 11, 65, 100, 101, 272, _
23456, 8007006005004003, 123, 00123.0, 1.23E2 }
For n As Integer = 0 To Ubound(t)
Print sayOrdinal(t(n))
Next n
 
Sleep</syntaxhighlight>
{{out}}
<pre>first
second
third
fourth
fifth
eleventh
sixty-fifth
one hundredth
one hundred first
two hundred seventy-second
twenty-three thousand four hundred fifty-sixth
eight quadrillion seven trillion six billion five million four thousand third
one hundred twenty-third
one hundred twenty-third
one hundred twenty-third</pre>
 
=={{header|Go}}==
As with the Kotlin solution, this uses the output of <code>say</code> from the
[[Number_names#Go|Number_names]] task.
<langsyntaxhighlight Golang="go">import (
"fmt"
"strings"
Line 594 ⟶ 949:
}
return t
}</langsyntaxhighlight>
{{output}}
<pre>first
Line 608 ⟶ 963:
twenty-three thousand four hundred fifty-sixth
eight quadrillion seven trillion six billion five million four thousand third</pre>
 
=={{header|Haskell}}==
Uses solution of [[Number_names#Haskell]]
 
<syntaxhighlight lang="haskell">spellOrdinal :: Integer -> String
spellOrdinal n
| n <= 0 = "not ordinal"
| n < 20 = small n
| n < 100 = case divMod n 10 of
(k, 0) -> spellInteger (10*k) ++ "th"
(k, m) -> spellInteger (10*k) ++ "-" ++ spellOrdinal m
| n < 1000 = case divMod n 100 of
(k, 0) -> spellInteger (100*k) ++ "th"
(k, m) -> spellInteger (100*k) ++ " and " ++ spellOrdinal m
| otherwise = case divMod n 1000 of
(k, 0) -> spellInteger (1000*k) ++ "th"
(k, m) -> spellInteger (k*1000) ++ s ++ spellOrdinal m
where s = if m < 100 then " and " else ", "
where
small = ([ undefined, "first", "second", "third", "fourth", "fifth"
, "sixth", "seventh", "eighth", "nineth", "tenth", "eleventh"
, "twelveth", "thirteenth", "fourteenth", "fifteenth", "sixteenth"
, "seventeenth", "eighteenth", "nineteenth"] !!) . fromEnum</syntaxhighlight>
 
Testing
 
<syntaxhighlight lang="haskell">main = mapM_ (\n -> putStrLn $ show n ++ "\t" ++ spellOrdinal n)
[1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003]</syntaxhighlight>
 
<pre>λ> main
1 first
2 second
3 third
4 fourth
5 fifth
11 eleventh
65 sixty-fifth
100 one hundredth
101 one hundred and first
272 two hundred and seventy-second
23456 twenty-three thousand, four hundred and fifty-sixth
8007006005004003 eight quadrillion, seven trillion, six billion, five million, four thousand and third</pre>
 
=={{header|J}}==
 
Here, we follow J's [[j:Vocabulary/Idioms#Ordinal_Number|best practice for ordinal numbers]], which is that 0 is first and 1 is second. This emphasizes the distinction between cardinal numbers like 0 and ordinal numbers like first, accurately represents array indices, and neatly captures a variety of related linguistic issues.
 
Also, we use definitions from the [[Number_names#J|number names task]] and the [[N%27th#J|N'th task]]:
 
<syntaxhighlight lang="j">ord=: {{
((us,suf)1+y) rplc ;:{{)n onest first twond second
threerd third fiveth fifth eightth eighth
}}-.LF
}}</syntaxhighlight>
 
Examples:
 
<syntaxhighlight lang="j"> ord 0
first
ord 1
second
ord 2
third
ord 3
fourth
ord 4
fifth
ord 5
sixth
ord 11
twelveth
ord 65
sixty-sixth
ord 100
one hundred first
ord 101
one hundred second
ord 272
two hundred seventy-third
ord 23456
twenty-three thousand four hundred fifty-seventh
ord 8007006005004003
eight quadrillion seven trillion six billion five million four thousand fourth
ord 123
one hundred twenty-fourth
ord 00123.0
one hundred twenty-fourth
ord 1.23e2
one hundred twenty-fourth</syntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">
import java.util.HashMap;
import java.util.Map;
Line 724 ⟶ 1,168:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 739 ⟶ 1,183:
23456 = twenty-three thousand four hundred fifty-sixth
8007006005004003 = eight quadrillion seven trillion six billion five million four thousand third
</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Also works with gojq and fq, the Go implementations'''
 
One point of interest in the following is that the program checks not
only that its integer input is within the scope of the program, but
also that it is within the capability of the C or Go platform.
In particular, `check_ok` checks for the platform's precision of
integer arithmetic.
 
For further remarks on this point, see the comments that
are included in the test data.
<syntaxhighlight lang=jq>
# integer division for precision when using gojq
def idivide($j):
. as $i
| ($i % $j) as $mod
| ($i - $mod) / $j ;
 
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
 
def small:
["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
 
def tens:
["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"];
 
# Up to 1e63 (vigintillion)
def illions:
["", " thousand", " million", " billion"," trillion", " quadrillion", " quintillion",
" sextillion", " septillion", " octillion", " nonillion", " decillion", " undecillion",
" duodecillion", " tredecillion", " quattuordecillion", " quindecillion",
" sexdecillion", " septendecillion", " octadecillion", " novemdecillion",
" vigintillion"
];
 
def illions($i):
if $i >= (illions|length) then "\($i * 3) zeros is beyond the scope of this exercise" | error
else illions[$i]
end;
 
def irregularOrdinals: {
"one": "first",
"two": "second",
"three": "third",
"five": "fifth",
"eight": "eighth",
"nine": "ninth",
"twelve": "twelfth"
};
 
def check_ok:
def ieee754:
9007199254740993==9007199254740992;
if ieee754
then if (. > 0 and (. + 1) == .) or (. < 0 and (. - 1) == .)
then "The number \(.) is too large for this platform" | error
else .
end
else .
end;
# error courtesy of illions/1 if order of magnitude is too large
def say:
check_ok
| { t: "", n: .}
| if .n < 0 then .t = "negative " | .n *= -1 else . end
| if .n < 20
then .t += small[.n]
elif .n < 100
then .t += tens[.n | idivide(10)]
| .s = .n % 10
| if .s > 0 then .t += "-" + small[.s] else . end
elif .n < 1000
then .t += small[.n | idivide(100)] + " hundred"
| .s = .n % 100
| if .s > 0 then .t += " " + (.s|say) else . end
else .sx = ""
| .i = 0
| until (.n <= 0;
.p = .n % 1000
| .n = (.n | idivide(1000))
| if .p > 0
then .ix = (.p|say) + illions(.i)
| if .sx != "" then .ix += " " + .sx else . end
| .sx = .ix
else .
end
| .i += 1 )
| .t += .sx
end
| .t ;
 
def sayOrdinal:
{n: ., s: say}
| .r = (.s | explode | reverse | implode)
| .i1 = (.r|index(" "))
| if .i1 then .i1 = (.s|length) - 1 - .i1 else . end
| .i2 = (.r|index("-"))
| if .i2 then .i2 = (.s|length) - 1 - .i2 else . end
# Set .i to 0 iff there was no space or hyphen:
| .i = (if .i1 or .i2 then 1 + ([.i1,.i2] | max) else 0 end)
# Now s[.i:] is the last word:
| irregularOrdinals[.s[.i:]] as $x
| if $x then .s[:.i] + $x
elif .s | endswith("y")
then .s[:-1] + "ieth"
else .s + "th"
end;
 
# Sample inputs
(1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456,
8007006005004003,
9007199254740991,
2e12,
9007199254740993, # too large for jq
# 1e63 is vigintillion so gojq should be able to handle 999 * 1e63
999000000000000000000000000000000000000000000000000000000000000000,
# ... but not 1000 vigintillion
1000000000000000000000000000000000000000000000000000000000000000000
)
| "\(lpad(10)) => \(sayOrdinal)"
</syntaxhighlight>
{{output}}
The output using gojq is shown first. The tail of the output
using jq is then shown to illustrate what happens when the program
determines the given integer is too large for jq's built-in support
for integer arithmetic.
 
'''Using gojq'''
<pre>
1 => first
2 => second
3 => third
4 => fourth
5 => fifth
11 => eleventh
65 => sixty-fifth
100 => one hundredth
101 => one hundred first
272 => two hundred seventy-second
23456 => twenty-three thousand four hundred fifty-sixth
8007006005004003 => eight quadrillion seven trillion six billion five million four thousand third
9007199254740991 => nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-first
2000000000000 => two trillionth
9007199254740993 => nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-third
999000000000000000000000000000000000000000000000000000000000000000 => nine hundred ninety-nine vigintillionth
gojq: error: 66 zeros is beyond the scope of this exercise
</pre>
'''Tail of output using the C implementation'''
<pre>
2000000000000 => two trillionth
jq: error (at <unknown>): The number 9007199254740992 is too large for this platform
</pre>
 
=={{header|Julia}}==
This makes use of code posted on this site by MichaeLeroy for a similar task at https://rosettacode.org/wiki/[[Number_names#Julia]]. The function num2text is used (but not included here) as posted from that location.
<syntaxhighlight lang="julia">
<lang Julia>
const irregular = Dict("one" => "first", "two" => "second", "three" => "third", "five" => "fifth",
"eight" => "eighth", "nine" => "ninth", "twelve" => "twelfth")
Line 775 ⟶ 1,378:
println("$n => $(numtext2ordinal(num2text(n)))")
end
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 794 ⟶ 1,397:
=={{header|Kotlin}}==
This makes use of the code at https://rosettacode.org/wiki/Number_names#Kotlin, which I also wrote, and adjusts it to output the corresponding ordinal. Although, for good measure, the program can deal with negative integers, zero and UK-style numbers (the insertion of 'and' at strategic places, no 'milliards' I promise!) none of these are actually tested in line with the task's requirements.
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
typealias IAE = IllegalArgumentException
Line 922 ⟶ 1,525:
val sa = arrayOf("123", "00123.0", "1.23e2")
for (s in sa) println("${"%16s".format(s)} = ${numToOrdinalText(s)}")
}</langsyntaxhighlight>
 
{{out}}
Line 943 ⟶ 1,546:
1.23e2 = one hundred twenty-third
</pre>
 
=={{header|Nim}}==
{{trans|Python}}
As in the Python solution, we reuse the output of <code>spellInteger</code> from the
[[Number_names#Nim|Number_names]] task.
 
<syntaxhighlight lang="nim">import strutils, algorithm, tables
 
const irregularOrdinals = {"one": "first",
"two": "second",
"three": "third",
"five": "fifth",
"eight": "eighth",
"nine": "ninth",
"twelve": "twelfth"}.toTable
 
const
tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
"eighty", "ninety"]
small = ["zero", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
huge = ["", "", "million", "billion", "trillion", "quadrillion",
"quintillion", "sextillion", "septillion", "octillion", "nonillion",
"decillion"]
 
# Forward reference.
proc spellInteger(n: int64): string
 
proc nonzero(c: string; n: int64; connect = ""): string =
if n == 0: "" else: connect & c & spellInteger(n)
 
proc lastAnd(num: string): string =
if ',' in num:
let pos = num.rfind(',')
var (pre, last) = if pos >= 0: (num[0 ..< pos], num[pos+1 .. num.high])
else: ("", num)
if " and " notin last: last = " and" & last
result = [pre, ",", last].join()
else:
result = num
 
proc big(e, n: int64): string =
if e == 0:
spellInteger(n)
elif e == 1:
spellInteger(n) & " thousand"
else:
spellInteger(n) & " " & huge[e]
 
iterator base1000Rev(n: int64): int64 =
var n = n
while n != 0:
let r = n mod 1000
n = n div 1000
yield r
 
proc spellInteger(n: int64): string =
if n < 0:
"minus " & spellInteger(-n)
elif n < 20:
small[int(n)]
elif n < 100:
let a = n div 10
let b = n mod 10
tens[int(a)] & nonzero("-", b)
elif n < 1000:
let a = n div 100
let b = n mod 100
small[int(a)] & " hundred" & nonzero(" ", b, " and")
else:
var sq = newSeq[string]()
var e = 0
for x in base1000Rev(n):
if x > 0: sq.add big(e, x)
inc e
reverse sq
lastAnd(sq.join(", "))
 
proc num2ordinal(n: SomeInteger|SomeFloat): string =
 
let n = n.int64
 
var num = spellInteger(n)
let hyphen = num.rsplit('-', 1)
var number = num.rsplit(' ', 1)
var delim = ' '
if number[^1].len > hyphen[^1].len:
number = hyphen
delim = '-'
 
if number[^1] in irregularOrdinals:
number[^1] = delim & irregularOrdinals[number[^1]]
elif number[^1].endswith('y'):
number[^1] = delim & number[^1][0..^2] & "ieth"
else:
number[^1] = delim & number[^1] & "th"
 
result = number.join()
 
 
when isMainModule:
 
const
tests1 = [int64 1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003, 123]
tests2 = [0123.0, 1.23e2]
 
for num in tests1:
echo "$1 => $2".format(num, num2ordinal(num))
for num in tests2:
echo "$1 => $2".format(num, num2ordinal(num))</syntaxhighlight>
 
{{out}}
<pre>1 => first
2 => second
3 => third
4 => fourth
5 => fifth
11 => eleventh
65 => sixty-fifth
100 => one hundredth
101 => one hundred and first
272 => two hundred and seventy-second
23456 => twenty-three thousand, four hundred and fifty-sixth
8007006005004003 => eight quadrillion, seven trillion, six billion, five million, four thousand, and third
123 => one hundred and twenty-third
123.0 => one hundred and twenty-third
123.0 => one hundred and twenty-third</pre>
 
=={{header|Perl}}==
Adding zero to the input forces a numeric conversion (any identity operation would suffice).
<langsyntaxhighlight lang="perl">use Lingua::EN::Numbers 'num2en_ordinal';
 
printf "%16s : %s\n", $_, num2en_ordinal(0+$_) for
<1 2 3 4 5 11 65 100 101 272 23456 8007006005004003 123 00123.0 '00123.0' 1.23e2 '1.23e2'>;</langsyntaxhighlight>
{{out}}
<pre> 1 : first
Line 970 ⟶ 1,701:
 
=={{header|Phix}}==
Standard builtin
<lang Phix>include demo\rosetta\number_names.exw
<!--<syntaxhighlight lang="phix">-->
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">65</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">101</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">272</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">23456</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8007006005004003</span><span style="color: #0000FF;">,</span>
constant {irregs,ordinals} = columnize({{"one","first"},
<span style="color: #000000;">123</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">00123.0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.23e2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0b1111011</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0o173</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0x7B</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">861</span><span style="color: #0000FF;">/</span><span style="color: #000000;">7</span><span style="color: #0000FF;">}</span>
{"two","second"},
{"three","third"},
{"five","fifth"},
{"eight","eighth"},
{"nine","ninth"},
{"twelve","twelfth"}})
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
function ordinal(string s)
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">ordinal</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])&</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
integer i
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=length(s) to 1 by -1 do
<!--</syntaxhighlight>-->
integer ch = s[i]
if ch=' ' or ch='-' then exit end if
end for
integer k = find(s[i+1..$],irregs)
if k then
s = s[1..i]&ordinals[k]
elsif s[$]='y' then
s[$..$] = "ieth"
else
s &= "th"
end if
return s
end function
 
constant tests = {1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003,
123, 00123.0, 1.23e2, 0b1111011, 0o173, 0x7B, 861/7}
 
for i=1 to length(tests) do
puts(1,ordinal(spell(tests[i]))&'\n')
end for</lang>
{{out}}
<pre>
Line 1,025 ⟶ 1,732:
one hundred and twenty-third
</pre>
 
As with the Go solution, this uses the output of spell_integer from the Number_names task (not included here).
 
=={{header|Prolog}}==
{{works with|SWI Prolog}}
<langsyntaxhighlight lang="prolog">test_ordinal(Number):-
number_name(Number, ordinal, Name),
writef('%w: %w\n', [Number, Name]).
Line 1,053 ⟶ 1,758:
test_ordinal(23456),
test_ordinal(7891233),
test_ordinal(8007006005004003).</langsyntaxhighlight>
 
Module for spelling numbers in US English:
<langsyntaxhighlight lang="prolog">:- module(number_name, [number_name/3]).
 
small_name(0, zero, zeroth).
Line 1,146 ⟶ 1,851:
atomic_list_concat([C, ' ', Name3], Name2)
),
atomic_list_concat([Name1, ' ', Name2], Name).</langsyntaxhighlight>
 
{{out}}
Line 1,176 ⟶ 1,881:
[[Number_names#Python|Number_names]] task.
 
<langsyntaxhighlight Pythonlang="python">irregularOrdinals = {
"one": "first",
"two": "second",
Line 1,262 ⟶ 1,967:
num = ", ".join([big(e, x) for e, x in
enumerate(base1000_rev(n)) if x][::-1])
return last_and(num)</langsyntaxhighlight>
<b>Output</b>
<pre>
Line 1,281 ⟶ 1,986:
1.23e2 => one hundred and twenty-third
</pre>
 
=={{header|Quackery}}==
 
<code>name$</code> is defined at [[Number names#Quackery]].
 
<code>switch</code>, <code>case</code>, and <code>otherwise</code> are defined at [[Metaprogramming#Quackery]].
 
<syntaxhighlight lang="Quackery"> [ name$
dup -2 split nip
[ switch
$ "ne" case
[ -3 split drop
$ "first" join ]
$ "wo" case
[ -3 split drop
$ "second" join ]
$ "ee" case
[ -3 split drop
$ "ird" join ]
$ "ve" case
[ -2 split drop
$ "fth" join ]
$ "ht" case
[ $ "h" join ]
$ "ty" case
[ -1 split drop
$ "ieth" join ]
otherwise
[ $ "th" join ] ] ] is nameth$ ( n --> $ )
 
' [ 1 2 3 4 5 11 65 100 101 272 23456 8007006005004003 ]
witheach
[ dup echo say " = " nameth$ echo$ cr ]</syntaxhighlight>
 
{{out}}
 
<pre>1 = first
2 = second
3 = third
4 = fourth
5 = fifth
11 = eleventh
65 = sixty fifth
100 = one hundredth
101 = one hundred and first
272 = two hundred and seventy second
23456 = twenty three thousand and four hundred and fifty sixth
8007006005004003 = eight quadrillion, seven trillion, six billion, five million, four thousand and third</pre>
 
=={{header|Raku}}==
Line 1,298 ⟶ 2,051:
It is not really clear what is meant by "Write a driver and a function...". Well, the function part is clear enough; driver not so much. Perhaps this will suffice.
 
<syntaxhighlight lang="raku" perl6line>use Lingua::EN::Numbers;
 
# The task
Line 1,323 ⟶ 2,076:
 
'Role Mixin',
'17' but 123;</langsyntaxhighlight>
{{out}}
<pre>Required tests:
Line 1,435 ⟶ 2,188:
 
=={{header|REXX}}==
<langsyntaxhighlight REXXlang="rexx">/*REXX programs spells out ordinal numbers (in English, using the American system). */
numeric digits 3000 /*just in case the user uses gihugic #s*/
parse arg n /*obtain optional arguments from the CL*/
Line 1,448 ⟶ 2,201:
os=$spell#(x pgmOpts) /*invoke REXX routine to spell ordinal#*/
say right(x, max(20, length(x) ) ) ' spelled ordinal number ───► ' os
end /*j*/</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 1,465 ⟶ 2,218:
</pre>
The &nbsp; '''$SPELL#.REX''' &nbsp; routine can be found here &nbsp; ───► &nbsp; [[$SPELL.REX|$SPELL#.REX]]. <br><br>
 
=={{header|Rust}}==
{{trans|C++}}
<syntaxhighlight lang="rust">struct NumberNames {
cardinal: &'static str,
ordinal: &'static str,
}
 
impl NumberNames {
fn get_name(&self, ordinal: bool) -> &'static str {
if ordinal {
return self.ordinal;
}
self.cardinal
}
}
 
const SMALL_NAMES: [NumberNames; 20] = [
NumberNames {
cardinal: "zero",
ordinal: "zeroth",
},
NumberNames {
cardinal: "one",
ordinal: "first",
},
NumberNames {
cardinal: "two",
ordinal: "second",
},
NumberNames {
cardinal: "three",
ordinal: "third",
},
NumberNames {
cardinal: "four",
ordinal: "fourth",
},
NumberNames {
cardinal: "five",
ordinal: "fifth",
},
NumberNames {
cardinal: "six",
ordinal: "sixth",
},
NumberNames {
cardinal: "seven",
ordinal: "seventh",
},
NumberNames {
cardinal: "eight",
ordinal: "eighth",
},
NumberNames {
cardinal: "nine",
ordinal: "ninth",
},
NumberNames {
cardinal: "ten",
ordinal: "tenth",
},
NumberNames {
cardinal: "eleven",
ordinal: "eleventh",
},
NumberNames {
cardinal: "twelve",
ordinal: "twelfth",
},
NumberNames {
cardinal: "thirteen",
ordinal: "thirteenth",
},
NumberNames {
cardinal: "fourteen",
ordinal: "fourteenth",
},
NumberNames {
cardinal: "fifteen",
ordinal: "fifteenth",
},
NumberNames {
cardinal: "sixteen",
ordinal: "sixteenth",
},
NumberNames {
cardinal: "seventeen",
ordinal: "seventeenth",
},
NumberNames {
cardinal: "eighteen",
ordinal: "eighteenth",
},
NumberNames {
cardinal: "nineteen",
ordinal: "nineteenth",
},
];
 
const TENS: [NumberNames; 8] = [
NumberNames {
cardinal: "twenty",
ordinal: "twentieth",
},
NumberNames {
cardinal: "thirty",
ordinal: "thirtieth",
},
NumberNames {
cardinal: "forty",
ordinal: "fortieth",
},
NumberNames {
cardinal: "fifty",
ordinal: "fiftieth",
},
NumberNames {
cardinal: "sixty",
ordinal: "sixtieth",
},
NumberNames {
cardinal: "seventy",
ordinal: "seventieth",
},
NumberNames {
cardinal: "eighty",
ordinal: "eightieth",
},
NumberNames {
cardinal: "ninety",
ordinal: "ninetieth",
},
];
 
struct NamedNumber {
cardinal: &'static str,
ordinal: &'static str,
number: usize,
}
 
impl NamedNumber {
fn get_name(&self, ordinal: bool) -> &'static str {
if ordinal {
return self.ordinal;
}
self.cardinal
}
}
 
const N: usize = 7;
const NAMED_NUMBERS: [NamedNumber; N] = [
NamedNumber {
cardinal: "hundred",
ordinal: "hundredth",
number: 100,
},
NamedNumber {
cardinal: "thousand",
ordinal: "thousandth",
number: 1000,
},
NamedNumber {
cardinal: "million",
ordinal: "millionth",
number: 1000000,
},
NamedNumber {
cardinal: "billion",
ordinal: "billionth",
number: 1000000000,
},
NamedNumber {
cardinal: "trillion",
ordinal: "trillionth",
number: 1000000000000,
},
NamedNumber {
cardinal: "quadrillion",
ordinal: "quadrillionth",
number: 1000000000000000,
},
NamedNumber {
cardinal: "quintillion",
ordinal: "quintillionth",
number: 1000000000000000000,
},
];
 
fn big_name(n: usize) -> &'static NamedNumber {
for i in 1..N {
if n < NAMED_NUMBERS[i].number {
return &NAMED_NUMBERS[i - 1];
}
}
&NAMED_NUMBERS[N - 1]
}
 
fn number_name(n: usize, ordinal: bool) -> String {
if n < 20 {
return String::from(SMALL_NAMES[n].get_name(ordinal));
} else if n < 100 {
if n % 10 == 0 {
return String::from(TENS[n / 10 - 2].get_name(ordinal));
}
let s1 = TENS[n / 10 - 2].get_name(false);
let s2 = SMALL_NAMES[n % 10].get_name(ordinal);
return format!("{}-{}", s1, s2);
}
let big = big_name(n);
let mut result = number_name(n / big.number, false);
result.push(' ');
if n % big.number == 0 {
result.push_str(big.get_name(ordinal));
} else {
result.push_str(big.get_name(false));
result.push(' ');
result.push_str(&number_name(n % big.number, ordinal));
}
result
}
 
fn test_ordinal(n: usize) {
println!("{}: {}", n, number_name(n, true));
}
 
fn main() {
test_ordinal(1);
test_ordinal(2);
test_ordinal(3);
test_ordinal(4);
test_ordinal(5);
test_ordinal(11);
test_ordinal(15);
test_ordinal(21);
test_ordinal(42);
test_ordinal(65);
test_ordinal(98);
test_ordinal(100);
test_ordinal(101);
test_ordinal(272);
test_ordinal(300);
test_ordinal(750);
test_ordinal(23456);
test_ordinal(7891233);
test_ordinal(8007006005004003);
}</syntaxhighlight>
 
{{out}}
<pre>
1: first
2: second
3: third
4: fourth
5: fifth
11: eleventh
15: fifteenth
21: twenty-first
42: forty-second
65: sixty-fifth
98: ninety-eighth
100: one hundredth
101: one hundred first
272: two hundred seventy-second
300: three hundredth
750: seven hundred fiftieth
23456: twenty-three thousand four hundred fifty-sixth
7891233: seven million eight hundred ninety-one thousand two hundred thirty-third
8007006005004003: eight quadrillion seven trillion six billion five million four thousand third
</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">var lingua_en = frequire('Lingua::EN::Numbers')
var tests = [1,2,3,4,5,11,65,100,101,272,23456,8007006005004003]
 
tests.each {|n|
printf("%16s : %s\n", n, lingua_en.num2en_ordinal(n))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,487 ⟶ 2,510:
23456 : twenty-three thousand four hundred and fifty-sixth
8007006005004003 : eight quadrillion, seven trillion, six billion, five million, four thousand and third
</pre>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">fileprivate class NumberNames {
let cardinal: String
let ordinal: String
 
init(cardinal: String, ordinal: String) {
self.cardinal = cardinal
self.ordinal = ordinal
}
func getName(_ ordinal: Bool) -> String {
return ordinal ? self.ordinal : self.cardinal
}
class func numberName(number: Int, ordinal: Bool) -> String {
guard number < 100 else {
return ""
}
if number < 20 {
return smallNames[number].getName(ordinal)
}
if number % 10 == 0 {
return tens[number/10 - 2].getName(ordinal)
}
var result = tens[number/10 - 2].getName(false)
result += "-"
result += smallNames[number % 10].getName(ordinal)
return result
}
static let smallNames = [
NumberNames(cardinal: "zero", ordinal: "zeroth"),
NumberNames(cardinal: "one", ordinal: "first"),
NumberNames(cardinal: "two", ordinal: "second"),
NumberNames(cardinal: "three", ordinal: "third"),
NumberNames(cardinal: "four", ordinal: "fourth"),
NumberNames(cardinal: "five", ordinal: "fifth"),
NumberNames(cardinal: "six", ordinal: "sixth"),
NumberNames(cardinal: "seven", ordinal: "seventh"),
NumberNames(cardinal: "eight", ordinal: "eighth"),
NumberNames(cardinal: "nine", ordinal: "ninth"),
NumberNames(cardinal: "ten", ordinal: "tenth"),
NumberNames(cardinal: "eleven", ordinal: "eleventh"),
NumberNames(cardinal: "twelve", ordinal: "twelfth"),
NumberNames(cardinal: "thirteen", ordinal: "thirteenth"),
NumberNames(cardinal: "fourteen", ordinal: "fourteenth"),
NumberNames(cardinal: "fifteen", ordinal: "fifteenth"),
NumberNames(cardinal: "sixteen", ordinal: "sixteenth"),
NumberNames(cardinal: "seventeen", ordinal: "seventeenth"),
NumberNames(cardinal: "eighteen", ordinal: "eighteenth"),
NumberNames(cardinal: "nineteen", ordinal: "nineteenth")
]
 
static let tens = [
NumberNames(cardinal: "twenty", ordinal: "twentieth"),
NumberNames(cardinal: "thirty", ordinal: "thirtieth"),
NumberNames(cardinal: "forty", ordinal: "fortieth"),
NumberNames(cardinal: "fifty", ordinal: "fiftieth"),
NumberNames(cardinal: "sixty", ordinal: "sixtieth"),
NumberNames(cardinal: "seventy", ordinal: "seventieth"),
NumberNames(cardinal: "eighty", ordinal: "eightieth"),
NumberNames(cardinal: "ninety", ordinal: "ninetieth")
]
}
 
fileprivate class NamedPower {
let cardinal: String
let ordinal: String
let number: UInt64
init(cardinal: String, ordinal: String, number: UInt64) {
self.cardinal = cardinal
self.ordinal = ordinal
self.number = number
}
func getName(_ ordinal: Bool) -> String {
return ordinal ? self.ordinal : self.cardinal
}
 
class func getNamedPower(_ number: UInt64) -> NamedPower {
for i in 1..<namedPowers.count {
if number < namedPowers[i].number {
return namedPowers[i - 1]
}
}
return namedPowers[namedPowers.count - 1]
}
 
static let namedPowers = [
NamedPower(cardinal: "hundred", ordinal: "hundredth",
number: 100),
NamedPower(cardinal: "thousand", ordinal: "thousandth",
number: 1000),
NamedPower(cardinal: "million", ordinal: "millionth",
number: 1000000),
NamedPower(cardinal: "billion", ordinal: "billionth",
number: 1000000000),
NamedPower(cardinal: "trillion", ordinal: "trillionth",
number: 1000000000000),
NamedPower(cardinal: "quadrillion", ordinal: "quadrillionth",
number: 1000000000000000),
NamedPower(cardinal: "quintillion", ordinal: "quintillionth",
number: 1000000000000000000)
]
}
 
public func numberName(number: UInt64, ordinal: Bool) -> String {
if number < 100 {
return NumberNames.numberName(number: Int(truncatingIfNeeded: number),
ordinal: ordinal)
}
let p = NamedPower.getNamedPower(number)
var result = numberName(number: number/p.number, ordinal: false)
result += " "
if number % p.number == 0 {
result += p.getName(ordinal)
} else {
result += p.getName(false)
result += " "
result += numberName(number: number % p.number, ordinal: ordinal)
}
return result
}
 
func printOrdinal(_ number: UInt64) {
print("\(number): \(numberName(number: number, ordinal: true))")
}
 
printOrdinal(1)
printOrdinal(2)
printOrdinal(3)
printOrdinal(4)
printOrdinal(5)
printOrdinal(11)
printOrdinal(15)
printOrdinal(21)
printOrdinal(42)
printOrdinal(65)
printOrdinal(98)
printOrdinal(100)
printOrdinal(101)
printOrdinal(272)
printOrdinal(300)
printOrdinal(750)
printOrdinal(23456)
printOrdinal(7891233)
printOrdinal(8007006005004003)</syntaxhighlight>
 
{{out}}
<pre>
1: first
2: second
3: third
4: fourth
5: fifth
11: eleventh
15: fifteenth
21: twenty-first
42: forty-second
65: sixty-fifth
98: ninety-eighth
100: one hundredth
101: one hundred first
272: two hundred seventy-second
300: three hundredth
750: seven hundred fiftieth
23456: twenty-three thousand four hundred fifty-sixth
7891233: seven million eight hundred ninety-one thousand two hundred thirty-third
8007006005004003: eight quadrillion seven trillion six billion five million four thousand third
</pre>
 
=={{header|VBA}}==
Inspired by the Phix solution. Uses [[Number_names#VBA|Number names]]
<langsyntaxhighlight lang="vb">Private Function ordinal(s As String) As String
Dim irregs As New Collection
irregs.Add "first", "one"
Line 1,523 ⟶ 2,718:
Debug.Print ordinal(spell(tests(i)))
Next i
End Sub</langsyntaxhighlight>{{out}}
<pre>first
second
Line 1,538 ⟶ 2,733:
one hundred and twenty-third
one hundred and twenty-third</pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
As with the Kotlin solution, this uses the output of <code>say</code> from the
[[Number_names#Go|Number_names]] task.
<syntaxhighlight lang="v (vlang)">fn main() {
for n in [i64(1), 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003,
] {
println(say_ordinal(n))
}
}
fn say_ordinal(n i64) string {
mut s := say(n)
mut i := s.last_index('-') or {s.last_index(' ') or {-1}}
i++
// Now s[:i] is everything upto and including the space or hyphen
// and s[i:] is the last word; we modify s[i:] as required.
// Since LastIndex returns -1 if there was no space/hyphen,
// `i` will be zero and this will still be fine.
ok := s[i..] in irregular_ordinals
x := irregular_ordinals[s[i..]]
if ok {
s = s[..i] + x
} else if s[s.len-1..s.len] == 'y' {
s = s[..i] + s[i..s.len-1] + "ieth"
} else {
s = s[..i] + s[i..] + "th"
}
return s
}
// Below is a copy of https://rosettacode.org/wiki/Number_names#Go
const (
small = ["zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
tens = ["", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"]
illions = ["", " thousand", " million", " billion",
" trillion", " quadrillion", " quintillion"]
irregular_ordinals = {
"one": "first",
"two": "second",
"three": "third",
"five": "fifth",
"eight": "eighth",
"nine": "ninth",
"twelve": "twelfth",
}
)
fn say(nn i64) string {
mut n := nn
mut t := ''
if n < 0 {
t = "negative "
// Note, for math.MinInt64 this leaves n negative.
n = -n
}
if n < 20{
t += small[n]
} else if n < 100{
t += tens[n/10]
s := n % 10
if s > 0 {
t += "-" + small[s]
}
} else if n < 1000{
t += small[n/100] + " hundred"
s := n % 100
if s > 0 {
t += " " + say(s)
}
} else {
// work right-to-left
mut sx := ""
for i := 0; n > 0; i++ {
p := n % 1000
n /= 1000
if p > 0 {
mut ix := say(p) + illions[i]
if sx != "" {
ix += " " + sx
}
sx = ix
}
}
t += sx
}
return t
}</syntaxhighlight>
{{output}}
<pre>first
second
third
fourth
fifth
eleventh
sixty-fifth
one hundredth
one hundred first
two hundred seventy-second
twenty-three thousand four hundred fifty-sixth
eight quadrillion seven trillion six billion five million four thousand third</pre>
 
=={{header|Wren}}==
{{trans|Go}}
This reuses the <code>say</code> function from the [[Number names#Wren|Number names]] task.
 
Note that it is not safe to use this script for numbers with an absolute magnitude >= 2^53 as integers cannot be expressed exactly by Wren's Num type beyond that limit.
<syntaxhighlight lang="wren">var small = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
 
var tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
 
var illions = ["", " thousand", " million", " billion"," trillion", " quadrillion", " quintillion"]
 
var irregularOrdinals = {
"one": "first",
"two": "second",
"three": "third",
"five": "fifth",
"eight": "eighth",
"nine": "ninth",
"twelve": "twelfth"
}
 
var say
say = Fn.new { |n|
var t = ""
if (n < 0) {
t = "negative "
n = -n
}
if (n < 20) {
t = t + small[n]
} else if (n < 100) {
t = t + tens[(n/10).floor]
var s = n % 10
if (s > 0) t = t + "-" + small[s]
} else if (n < 1000) {
t = t + small[(n/100).floor] + " hundred"
var s = n % 100
System.write("") // guards against VM recursion bug
if (s > 0) t = t + " " + say.call(s)
} else {
var sx = ""
var i = 0
while (n > 0) {
var p = n % 1000
n = (n/1000).floor
if (p > 0) {
System.write("") // guards against VM recursion bug
var ix = say.call(p) + illions[i]
if (sx != "") ix = ix + " " + sx
sx = ix
}
i = i + 1
}
t = t + sx
}
return t
}
 
var sayOrdinal = Fn.new { |n|
var s = say.call(n)
var r = s[-1..0]
var i1 = r.indexOf(" ")
if (i1 != -1) i1 = s.count - 1 - i1
var i2 = r.indexOf("-")
if (i2 != -1) i2 = s.count - 1 - i2
var i = (i1 > i2) ? i1 : i2
i = i + 1
// Now s[0...i] is everything up to and including the space or hyphen
// and s[i..-1] is the last word; we modify s[i..-1] as required.
// Since indexOf returns -1 if there was no space/hyphen,
// `i` will be zero and this will still be fine.
var x = irregularOrdinals[s[i..-1]]
if (x) {
return s[0...i] + x
} else if (s[-1] == "y") {
return s[0...i] + s[i..-2] + "ieth"
} else {
return s[0...i] + s[i..-1] + "th"
}
}
 
for (n in [1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 9007199254740991]) {
System.print(sayOrdinal.call(n))
}</syntaxhighlight>
 
{{out}}
<pre>
first
second
third
fourth
fifth
eleventh
sixty-fifth
one hundredth
one hundred first
two hundred seventy-second
twenty-three thousand four hundred fifty-sixth
nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-first
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn nth(n,th=True){
var [const]
nmsth=T("","first","second","third","fourth","fifth","sixth","seventh","eighth","ninth"),
Line 1,570 ⟶ 2,973:
}
}
fcn dash(n,d,th){ if(n) String(d,nth(n,th)) else (th and "th" or "") }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">testNs:=L(1,2,3,4,5,11,65,100,101,272,23456,8007006005004003,
123,00123.0,1.23e2,);
foreach n in (testNs){
if(n.isType(Float)) println("%16.2f --> %s".fmt(n,nth(n)));
else println("%16d --> %s".fmt(n,nth(n)));
}</langsyntaxhighlight>
{{out}}
<pre>
2,122

edits