Ordinal numbers   (as used in this Rosetta Code task),   are numbers that describe the   position   of something in a list.

It is this context that ordinal numbers will be used, using an English-spelled name of an ordinal number.



The ordinal numbers are   (at least, one form of them):

  1st  2nd  3rd  4th  5th  6th  7th  ···  99th  100th  ···  1000000000th  ···  etc

sometimes expressed as:

  1st  2nd  3rd  4th  5th  6th  7th  ···  99th  100th  ···  1000000000th  ···



For this task, the following (English-spelled form) will be used:

  first second third fourth fifth sixth seventh ninety-nineth one hundredth one billionth



Furthermore, the American version of numbers will be used here   (as opposed to the British).

2,000,000,000   is two billion,   not   two milliard.



Task

Write a driver and a function (subroutine/routine ···) that returns the English-spelled ordinal version of a specified number   (a positive integer).

Optionally, try to support as many forms of an integer that can be expressed:   123   00123.0   1.23e2   all are forms of the same integer.

Show all output here.



Test cases

Use (at least) the test cases of:

  1  2  3  4  5  11  65  100  101  272  23456  8007006005004003



Related tasks

   Number names
   N'th


fcn nth(n,th=True){
   var [const]
     nmsth=T("","first","second","third","fourth","fifth","sixth","seventh","eighth","ninth"),
     nms1=T("","one","two","three","four","five","six","seven","eight","nine"),
     nms10=T("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"),
     nms10th=T("tenth","eleventh","twelfth","thirteenth","fourteenth","fifteenth","sixteenth","seventeenth","eighteenth","nineteenth"),
     nms20=T("twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"),
     nms1000=T("thousand","million","billion","trillion","quadrillion"); // 3,6,9,12,15
 
   if     (n<0)  String("negative ",nth(-n,th));
   else if(n<10) th and nmsth[n] or nms1[n];
   else if(n<20) th and nms10th[n-10] or nms10[n-10];
   else if(n<10) th and nmsth[n] or nms1[n];
   else if(n<100){
      m,txt := n%10,nms20[n/10-2];
      if(m) String(txt,dash(n%10,"-",th));
      else  String(txt[0,-1],"ieth");
   }
   else if(n<1000) String(nms1[n/100]," hundred",dash(n%100," ",th));
   else{
      n=n.toInt();   // yuck, only here to handle floats, 1.23-->"first"
      ds:=(n.numDigits()-1)/3*3; // 1e3->3, 1e4-->3, 1e5-->3, 1e6-->6, 1e7-->6
      z:=(10).pow(ds);  // 1234-->1000, 12345-->10000
      thou:=ds/3 - 1;	// 1000-->0, 10000-->0, 2,000,000-->1
      nnn,ys := n/z, n%z;
      String((if(nnn<10) nms1[nnn] else nth(nnn,False)),
	  " ",nms1000[thou],
	  if(ys==0) "th" else String(" ",nth(ys,th)));
   }
}
fcn dash(n,d,th){ if(n) String(d,nth(n,th)) else (th and "th" or "") }