home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / packs / skeem / sknumber.icn < prev    next >
Text File  |  2000-07-29  |  7KB  |  441 lines

  1. ############################################################################
  2. #
  3. #    Name:    sknumber.icn
  4. #
  5. #    Title:    Scheme in Icon
  6. #
  7. #    Author: Bob Alexander
  8. #
  9. #    Date:    March 23, 1995
  10. #
  11. #    Description: see skeem.icn
  12. #
  13. ############################################################################
  14.  
  15. #
  16. # skeem -- Scheme in Icon
  17. #
  18. # Number procedures
  19. #
  20.  
  21. #
  22. # Initialize
  23. #
  24. # List entries are described in skfun.icn.
  25. #
  26. procedure InitNumber()
  27.    DefFunction([
  28.       ABS,
  29.       ACOS,
  30.       ADD,&null,"+",
  31.       ASIN,
  32.       ATAN,1,2,
  33.       CEILING,
  34.       COMPLEX_P,
  35.       COS,
  36.       DIVIDE,"oneOrMore","/",
  37.       EQ,"twoOrMore","=",
  38.       EVEN_P,
  39.       EXACT_2_INEXACT,
  40.       EXACT_P,
  41.       EXP,
  42.       EXPT,2,
  43.       FLOOR,
  44.       GCD,&null,
  45.       GE,"twoOrMore",">=",
  46.       GT,"twoOrMore",">",
  47.       INEXACT_2_EXACT,
  48.       INEXACT_P,
  49.       INTEGER_P,
  50.       LCM,&null,
  51.       LE,"twoOrMore","<=",
  52.       LOG,
  53.       LT,"twoOrMore","<",
  54.       MAX,"oneOrMore",
  55.       MIN,"oneOrMore",
  56.       MODULO,2,
  57.       MULTIPLY,&null,"*",
  58.       NE,"twoOrMore","<>",
  59.       NEGATIVE_P,
  60.       NUMBER_2_STRING,1,2,
  61.       NUMBER_P,
  62.       ODD_P,
  63.       POSITIVE_P,
  64.       QUOTIENT,2,
  65.       RATIONAL_P,
  66.       REAL_P,
  67.       REMAINDER,2,
  68.       ROUND,
  69.       SIN,
  70.       SQRT,
  71.       STRING_2_NUMBER,1,2,
  72.       SUBTRACT,"oneOrMore","-",
  73.       TAN,
  74.       TRUNCATE,
  75.       ZERO_P])
  76.    return
  77. end
  78.  
  79.  
  80. #
  81. # Numbers
  82. #
  83.  
  84. procedure NUMBER_P(x)
  85.    return REAL_P(x)
  86. end
  87.  
  88. procedure COMPLEX_P(x)
  89.    return REAL_P(x)
  90. end
  91.  
  92. procedure REAL_P(x)
  93.    return (type(x) == ("integer" | "real"),T) | F
  94. end
  95.  
  96. procedure RATIONAL_P(x)
  97.    return INTEGER_P(x)
  98. end
  99.  
  100. procedure INTEGER_P(x)
  101.    return (type(x) == "integer",T) | F
  102. end
  103.  
  104. procedure EXACT_P(x)
  105.    return (type(numeric(x)) == "real",F) | T
  106. end
  107.  
  108. procedure INEXACT_P(x)
  109.    return (type(numeric(x)) == "real",T) | F
  110. end
  111.  
  112. invocable "<":2
  113.  
  114. procedure LT(n[])
  115.    static op
  116.    initial op := proc("<",2)
  117.    return NumericPredicate(n,op)
  118. end
  119.  
  120. invocable "<=":2
  121.  
  122. procedure LE(n[])
  123.    static op
  124.    initial op := proc("<=",2)
  125.    return NumericPredicate(n,op)
  126. end
  127.  
  128. invocable "=":2
  129.  
  130. procedure EQ(n[])
  131.    static op
  132.    initial op := proc("=",2)
  133.    return NumericPredicate(n,op)
  134. end
  135.  
  136. invocable ">=":2
  137.  
  138. procedure GE(n[])
  139.    static op
  140.    initial op := proc(">=",2)
  141.    return NumericPredicate(n,op)
  142. end
  143.  
  144. invocable ">":2
  145.  
  146. procedure GT(n[])
  147.    static op
  148.    initial op := proc(">",2)
  149.    return NumericPredicate(n,op)
  150. end
  151.  
  152. invocable "~=":2
  153.  
  154. procedure NE(n[])
  155.    static op
  156.    initial op := proc("~=",2)
  157.    return NumericPredicate(n,op)
  158. end
  159.  
  160. procedure ZERO_P(n)
  161.    return (n = 0,T) | F
  162. end
  163.  
  164. procedure POSITIVE_P(n)
  165.    return (n > 0,T) | F
  166. end
  167.  
  168. procedure NEGATIVE_P(n)
  169.    return (n < 0,T) | F
  170. end
  171.  
  172. procedure ODD_P(n)
  173.    return (n % 2 ~= 0,T) | F
  174. end
  175.  
  176. procedure EVEN_P(n)
  177.    return (n % 2 = 0,T) | F
  178. end
  179.  
  180. procedure MAX(n[])
  181.    local result,x
  182.    result := get(n)
  183.    every x := !n do {
  184.       if type(x) == "real" then result := real(result)
  185.       result <:= x
  186.       }
  187.    return result
  188. end
  189.  
  190. procedure MIN(n[])
  191.    local result,x
  192.    result := get(n)
  193.    every x := !n do {
  194.       if type(x) == "real" then result := real(result)
  195.       result >:= x
  196.       }
  197.    return result
  198. end
  199.  
  200. invocable "+":2,"+":1
  201.  
  202. procedure ADD(n[])
  203.    static op,op1
  204.    initial {
  205.       op := proc("+",2)
  206.       op1 := proc("+",1)
  207.       }
  208.    return Arithmetic(n,op,op1,0)
  209. end
  210.  
  211. invocable "*":2,"+":1
  212.  
  213. procedure MULTIPLY(n[])
  214.    static op,op1
  215.    initial {
  216.       op := proc("*",2)
  217.       op1 := proc("+",1)
  218.       }
  219.    return Arithmetic(n,op,op1,1)
  220. end
  221.  
  222. invocable "-":2,"-":1
  223.  
  224. procedure SUBTRACT(n[])
  225.    static op,op1
  226.    initial {
  227.       op := proc("-",2)
  228.       op1 := proc("-",1)
  229.       }
  230.    return Arithmetic(n,op,op1)
  231. end
  232.  
  233. procedure DIVIDE(n[])
  234.    return Arithmetic(n,Divide,Reciprocal)
  235. end
  236.  
  237. procedure Divide(n1,n2)
  238.    return n1 / ZeroDivCheck(DIVIDE,n2)
  239. end
  240.  
  241. procedure Reciprocal(n)
  242.    return Divide(1.0,n)
  243. end
  244.  
  245. procedure ZeroDivCheck(fName,n)
  246.    return if n = 0 then Error(fName,"divide by zero") else n
  247. end
  248.  
  249. procedure ABS(n)
  250.    return abs(n)
  251. end
  252.  
  253. procedure QUOTIENT(num,den)
  254.    return integer(num) / ZeroDivCheck(QUOTIENT,integer(den))
  255. end
  256.  
  257. procedure REMAINDER(num,den)
  258.    return num % ZeroDivCheck(REMAINDER,den)
  259. end
  260.  
  261. procedure MODULO(num,den)
  262.    local result
  263.    result := num % ZeroDivCheck(REMAINDER,den)
  264.    if result ~= 0 then
  265.       result +:= if 0 > num then 0 <= den else 0 > den
  266.    return result
  267. end
  268.  
  269. procedure GCD(n[])
  270.    local min,i,areal,x
  271.    min := 0 < abs(!n)
  272.    if /min then return 0
  273.    every i := 1 to *n do {
  274.       x := numeric(n[i])
  275.       areal := type(x) == "real"
  276.       min >:= 0 < (n[i] := abs(x))
  277.       }
  278.    x := ((every i := min to 2 by -1 do !n % i ~= 0 | break),i) | 1
  279.    return (\areal,real(x)) | x
  280. end
  281.  
  282. procedure LCM(n[])
  283.    local max,i,areal,x
  284.    max := 0
  285.    every i := 1 to *n do {
  286.       x := numeric(n[i])
  287.       areal := type(x) == "real"
  288.       max <:= n[i] := abs(x)
  289.       }
  290.    if max = 0 then return 1
  291.    x := ((every i := seq(max,max) do i % !n ~= 0 | break),i)
  292.    return (\areal,real(x)) | x
  293. end
  294.  
  295. procedure FLOOR(n)
  296.    local intn
  297.    if type(n) == "integer" then return n
  298.    intn := integer(n)
  299.    return real(if n < 0.0 & n ~= intn then intn - 1 else intn)
  300. end
  301.  
  302. procedure CEILING(n)
  303.    local intn
  304.    if type(n) == "integer" then return n
  305.    intn := integer(n)
  306.    return real(if n > 0.0 & n ~= intn then intn + 1 else intn)
  307. end
  308.  
  309. procedure TRUNCATE(n)
  310.    return (type(n) == "integer",n) | real(integer(n))
  311. end
  312.  
  313. procedure ROUND(n)
  314.    return (
  315.       if type(n) == "integer" then n
  316.       else real(Round(n)))
  317. end
  318.  
  319. procedure Round(n)
  320.    local intn,diff
  321.    intn := integer(n)
  322.    diff := abs(n) - abs(intn)
  323.    return (
  324.       if diff < 0.5 then intn
  325.       else if diff > 0.5 then
  326.      if n < 0.0 then intn - 1
  327.      else intn + 1
  328.       else if intn % 2 = 0 then
  329.      intn
  330.       else if n < 0.0 then
  331.      intn - 1
  332.       else
  333.      intn + 1)
  334. end
  335.  
  336. procedure EXP(n)
  337.    return exp(n)
  338. end
  339.  
  340. procedure LOG(n)
  341.    return log(n)
  342. end
  343.  
  344. procedure SIN(n)
  345.    return sin(n)
  346. end
  347.  
  348. procedure COS(n)
  349.    return cos(n)
  350. end
  351.  
  352. procedure TAN(n)
  353.    return tan(n)
  354. end
  355.  
  356. procedure ASIN(n)
  357.    return asin(n)
  358. end
  359.  
  360. procedure ACOS(n)
  361.    return acos(n)
  362. end
  363.  
  364. procedure ATAN(num,den)
  365.    return atan(num,den)
  366. end
  367.  
  368. procedure SQRT(n)
  369.    return sqrt(n)
  370. end
  371.  
  372. procedure EXPT(n1,n2)
  373.    return n1 ^ n2
  374. end
  375.  
  376. procedure EXACT_2_INEXACT(n)
  377.    return real(n)
  378. end
  379.  
  380. procedure INEXACT_2_EXACT(n)
  381.    return Round(n)
  382. end
  383.  
  384.  
  385. #
  386. # Numerical input and output.
  387. #
  388.  
  389. procedure STRING_2_NUMBER(s,rx)
  390.    return StringToNumber(s.value,rx) | F
  391. end
  392.  
  393. procedure NUMBER_2_STRING(n,rx)
  394.    return String(
  395.       if \rx ~= 10 then
  396.      AsRadix(n,rx)
  397.       else
  398.      string(n)
  399.       ) | Error(NUMBER_2_STRING,"can't convert")
  400. end
  401.  
  402. #
  403. # Procedure to return print representation of a number in specified
  404. # radix (2 - 36).
  405. #
  406. procedure AsRadix(i,radix)
  407.   local result,sign
  408.   static digits
  409.   initial digits := &digits || &lcase
  410.   if radix <= 1 then runerr(205,radix)
  411.   if i = 0 then return "0"
  412.   sign := (i < 0,"-") | ""
  413.   i := abs(i)
  414.   result := ""
  415.   until i = 0 do {
  416.     result := (digits[i % radix + 1] | fail) || result
  417.     i /:= radix
  418.   }
  419.   return sign || result
  420. end
  421.  
  422. procedure Arithmetic(nList,op,op1,zeroArgValue)
  423.    local result,x
  424.    if not nList[1] then return \zeroArgValue
  425.    if not nList[2] & \op1 then return op1(nList[1])
  426.    else {
  427.       result := get(nList)
  428.       every x := !nList do
  429.      result := op(result,x) | fail
  430.       return result
  431.       }
  432. end
  433.  
  434. procedure NumericPredicate(nList,op)
  435.    local result,x
  436.    result := get(nList)
  437.    every x := !nList do
  438.       result := op(result,x) | (if &errornumber then fail else return F)
  439.    return T
  440. end
  441.