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

  1. ############################################################################
  2. #
  3. #    Name:    rational.icn
  4. #
  5. #    Title:    Perform arithmetic on rational numbers
  6. #
  7. #    Author:    Ralph E. Griswold
  8. #
  9. #    Date:    May 11, 1989
  10. #
  11. ############################################################################
  12. #
  13. #     These procedures perform arithmetic on rational numbers (fractions):
  14. #
  15. #     str2rst(s)    Convert the string representation of a rational number
  16. #                   (such as "3/2") to a rational number.
  17. #
  18. #     rat2str(r)    Convert the rational number r to its string
  19. #                   representation.
  20. #
  21. #     addrat(r1,r2) Add rational numbers r1 and r2.
  22. #
  23. #     subrat(r1,r2) Subtract rational numbers r1 and r2.
  24. #
  25. #     mpyrat(r1,r2) Multiply rational numbers r1 and r2.
  26. #
  27. #     divrat(r1,r2) Divide rational numbers r1 and r2.
  28. #
  29. #     negrat(r)     Produce negative of rational number r.
  30. #
  31. #     reciprat(r)   Produce the reciprocal of rational number r.
  32. #    
  33. ############################################################################
  34. #
  35. #  Links: gcd
  36. #
  37. ############################################################################
  38.  
  39. link gcd
  40.  
  41. record rational(numer,denom,sign)
  42.  
  43. procedure str2rat(s)
  44.    local div, numer, denom, sign
  45.  
  46.    s ? {
  47.       ="[" &
  48.       numer := integer(tab(upto('/'))) &
  49.       move(1) &
  50.       denom := integer(tab(upto(']'))) &
  51.       pos(-1)
  52.       } | fail
  53.    div := gcd(numer,denom) | fail
  54.    numer /:= div
  55.    denom /:= div
  56.    if numer * denom >= 0 then sign := 1    # dangerous -- potential overflow
  57.       else sign := -1
  58.    return rational(abs(numer),abs(denom),sign)
  59. end
  60.   
  61. procedure rat2str(r)
  62.    return "[" || r.numer * r.sign || "/" || r.denom || "]"
  63. end
  64.  
  65. procedure mpyrat(r1,r2)
  66.    local numer, denom, div
  67.  
  68.    numer := r1.numer * r2.numer
  69.    denom := r1.denom * r2.denom
  70.    div := gcd(numer,denom) | fail    # shouldn't fail
  71.    return rational(numer / div,denom / div, r1.sign * r2.sign)
  72. end
  73.  
  74. procedure divrat(r1,r2)
  75.    return mpyrat(r1,reciprat(r2))    # may fail
  76. end
  77.  
  78. procedure reciprat(r)
  79.    if r.numer = 0 then fail
  80.    else return rational(r.denom,r.numer,r.sign)
  81. end
  82.  
  83. procedure negrat(r)
  84.    return rational(r.numer,r.denom,-r.sign)
  85. end
  86.  
  87. procedure addrat(r1,r2)
  88.    local denom, numer, div, sign
  89.  
  90.    denom := r1.denom * r2.denom
  91.    numer := r1.sign * r1.numer * r2.denom +
  92.       r2.sign * r2.numer * r1.denom
  93.    if numer >= 0 then sign := 1
  94.       else sign := -1
  95.    div := gcd(numer,denom) | fail
  96.    return rational(abs(numer / div),abs(denom / div),sign)
  97. end
  98.  
  99. procedure subrat(r1,r2)
  100.    return addrat(r1,negrat(r2))
  101. end
  102.