home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OL.LZH / PROCS.LZH / NUMBERS.ICN < prev    next >
Text File  |  1991-09-05  |  3KB  |  107 lines

  1. ###########################################################################
  2. #
  3. #    Name:    numbers.icn
  4. #
  5. #    Title:    Format and convert numbers
  6. #
  7. #    Author:    Ralph E. Griswold and Tim Korb
  8. #
  9. #    Date:    February 1, 1991
  10. #
  11. ############################################################################
  12. #
  13. #     These procedures format numbers in various ways:
  14. #
  15. #     commas(s)        inserts commas in s to separate digits into groups of
  16. #            three.
  17. #
  18. #     roman(i)        converts s to Roman numerals.
  19. #
  20. #     spell(i)        spells out i in English.
  21. #
  22. #     fix(i,j,w,d)    formats i / j as a real (floating-point) number in
  23. #            a field of width w with d digits to the right of
  24. #            the decimal point, if possible. j defaults to 1,
  25. #            w to 8, and d to 3. If w is less than 3 it is set
  26. #            to 3. If d is less than 1, it is set to 1. The
  27. #            function fails if j is 0.
  28. #
  29. ############################################################################
  30.  
  31. procedure commas(n)
  32.    if *n < 4 then return n
  33.    else return commas(left(n,*n - 3)) || map(",123","123",right(n,3))
  34. end
  35.  
  36. #  This procedure is based on a SNOBOL4 function written by Jim Gimpel.
  37. #
  38. procedure roman(n)
  39.    local arabic, result
  40.    static equiv
  41.    initial equiv := ["","I","II","III","IV","V","VI","VII","VIII","IX"]
  42.    integer(n) > 0 | fail
  43.    result := ""
  44.    every arabic := !n do
  45.       result := map(result,"IVXLCDM","XLCDM**") || equiv[arabic + 1]
  46.    if find("*",result) then fail else return result
  47. end
  48.  
  49. procedure spell(n)
  50.    local m
  51.    n := integer(n) | stop(image(n)," is not an integer")
  52.    if n <= 12 then return {
  53.       "0zero,1one,2two,3three,4four,5five,6six,7seven,8eight,_
  54.          9nine,10ten,11eleven,12twelve," ? {
  55.             tab(find(n))
  56.             move(*n)
  57.             tab(upto(","))
  58.             }
  59.       }
  60.    else if n <= 19 then return {
  61.       spell(n[2] || "0") ?
  62.          (if ="for" then "four" else tab(find("ty"))) || "teen"
  63.       }
  64.    else if n <= 99 then return {
  65.       "2twen,3thir,4for,5fif,6six,7seven,8eigh,9nine," ? {
  66.          tab(upto(n[1]))
  67.          move(1)
  68.          tab(upto(",")) || "ty" ||
  69.             if n[2] ~= 0 then "-" || spell(n[2])
  70.          }
  71.       }
  72.    else if n <= 999 then return {
  73.       spell(n[1]) || " hundred" ||
  74.          (if (m := n[2:0]) ~= 0 then " and " || spell(m) else "")
  75.       }
  76.    else if n <= 999999 then return {
  77.       spell(n[1:-3]) || " thousand" ||
  78.          (if (m := n[2:0]) ~= 0 then " and " || spell(m) else "")
  79.       }
  80.    else if n <= 999999999 then return {
  81.       spell(n[1:-6]) || " million" ||
  82.          (if (m := n[2:0]) ~= 0 then " and " || spell(m) else "")
  83.       }
  84.    else fail
  85. end
  86.  
  87. procedure fix(i,j,w,d)
  88.    local r, int, dec
  89.  
  90.    /j := 1
  91.    /w := 8
  92.    /d := 3
  93.    if j = 0 then fail
  94.    w <:= 3
  95.    d <:= 1
  96.    r := real(i) / j
  97.    string(r) ? {
  98.       if int := tab(upto('.')) then {
  99.          move(1)
  100.          dec := tab(0)
  101.          }
  102.       else int := dec := "0"        # no decimal point; punt.
  103.       }
  104.    if *int < w - d + 1 then int := right(int,w - d + 1)
  105.    return int || "." || left(dec,d,"0")
  106. end
  107.