home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / BIPL.ZIP / PROCS.ZIP / NUMBERS.ICN < prev    next >
Encoding:
Text File  |  1992-09-28  |  3.2 KB  |  116 lines

  1. ###########################################################################
  2. #
  3. #    File:     numbers.icn
  4. #
  5. #    Subject:  Procedures to 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 or if the number cannot
  28. #            be formatted.
  29. #
  30. ############################################################################
  31.  
  32. procedure commas(n)
  33.    if *n < 4 then return n
  34.    else return commas(left(n,*n - 3)) || map(",123","123",right(n,3))
  35. end
  36.  
  37. #  This procedure is based on a SNOBOL4 function written by Jim Gimpel.
  38. #
  39. procedure roman(n)
  40.    local arabic, result
  41.    static equiv
  42.    initial equiv := ["","I","II","III","IV","V","VI","VII","VIII","IX"]
  43.    integer(n) > 0 | fail
  44.    result := ""
  45.    every arabic := !n do
  46.       result := map(result,"IVXLCDM","XLCDM**") || equiv[arabic + 1]
  47.    if find("*",result) then fail else return result
  48. end
  49.  
  50. procedure spell(n)
  51.    local m
  52.    n := integer(n) | stop(image(n)," is not an integer")
  53.    if n <= 12 then return {
  54.       "0zero,1one,2two,3three,4four,5five,6six,7seven,8eight,_
  55.          9nine,10ten,11eleven,12twelve," ? {
  56.             tab(find(n))
  57.             move(*n)
  58.             tab(find(","))
  59.             }
  60.       }
  61.    else if n <= 19 then return {
  62.       spell(n[2] || "0") ?
  63.          (if ="for" then "four" else tab(find("ty"))) || "teen"
  64.       }
  65.    else if n <= 99 then return {
  66.       "2twen,3thir,4for,5fif,6six,7seven,8eigh,9nine," ? {
  67.          tab(find(n[1]))
  68.          move(1)
  69.          tab(find(",")) || "ty" ||
  70.             if n[2] ~= 0 then "-" || spell(n[2])
  71.          }
  72.       }
  73.    else if n <= 999 then return {
  74.       spell(n[1]) || " hundred" ||
  75.          (if (m := n[2:0]) ~= 0 then " and " || spell(m) else "")
  76.       }
  77.    else if n <= 999999 then return {
  78.       spell(n[1:-3]) || " thousand" ||
  79.          (if (m := n[2:0]) ~= 0 then " and " || spell(m) else "")
  80.       }
  81.    else if n <= 999999999 then return {
  82.       spell(n[1:-6]) || " million" ||
  83.          (if (m := n[2:0]) ~= 0 then " and " || spell(m) else "")
  84.       }
  85.    else fail
  86. end
  87.  
  88. procedure fix(i,j,w,d)
  89.    local r, int, dec
  90.  
  91.    /j := 1
  92.    /w := 8
  93.    /d := 3
  94.    if j = 0 then fail
  95.    w <:= 3
  96.    d <:= 1
  97.    r := real(i) / j
  98.  
  99.    int := dec := "0"                # prepare for small number
  100.  
  101.    if not(r < ("0." || repl("0", d - 1) || "1")) then {    # formats as zero
  102.       string(r) ? {
  103.          if upto('eE') then fail        # can't format
  104.          if int := tab(find(".")) then {
  105.             move(1)
  106.             dec := tab(0)
  107.             }
  108.          }
  109.       }
  110.  
  111.    if *int < w - d + 1 then int := right(int,w - d + 1)
  112.  
  113.    return int || "." || left(dec,d,"0")
  114.  
  115. end
  116.