rational.red 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. module rational; % *** Tables for rational numbers ***.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1987 The RAND Corporation. All rights reserved.
  4. global '(domainlist!*);
  5. switch rational;
  6. domainlist!* := union('(!:rn!:),domainlist!*);
  7. put('rational,'tag,'!:rn!:);
  8. put('!:rn!:,'dname,'rational);
  9. flag('(!:rn!:),'field);
  10. put('!:rn!:,'i2d,'!*i2rn);
  11. put('!:rn!:,'!:ft!:,'!*rn2ft);
  12. put('!:rn!:,'minus,'rnminus!:);
  13. put('!:rn!:,'minusp,'rnminusp!:);
  14. put('!:rn!:,'plus,'rnplus!:);
  15. put('!:rn!:,'times,'rntimes!:);
  16. put('!:rn!:,'difference,'rndifference!:);
  17. put('!:rn!:,'quotient,'rnquotient!:);
  18. put('!:rn!:,'zerop,'rnzerop!:);
  19. put('!:rn!:,'onep,'rnonep!:);
  20. put('!:rn!:,'factorfn,'rnfactor!:);
  21. put('!:rn!:,'expt,'rnexpt!:);
  22. put('!:rn!:,'prepfn,'rnprep!:);
  23. put('!:rn!:,'prifn,'rnprin);
  24. put('!:rn!:,'intequivfn,'rnequiv);
  25. put('!:rn!:,'rootfn,'rn!:root);
  26. flag('(!:rn!:),'ratmode);
  27. symbolic procedure rnexpt!:(u,n);
  28. % U is a tagged rational number, n an integer.
  29. begin scalar v;
  30. if n=0 then return 1;
  31. v:=cdr u;
  32. if (n<0) then <<
  33. n:=-n;
  34. if (car v < 0) then
  35. v:= (- cdr v) . (- car v)
  36. else v:= (cdr v) . (car v) >>;
  37. if (n=1) then return (car u) . v;
  38. return (car u) . ((car v ** n) . (cdr v ** n));
  39. % No more cancellation can take place in this exponentiation.
  40. end;
  41. symbolic procedure mkratnum u;
  42. % U is a domain element. Value is equivalent real or complex
  43. % rational number.
  44. if atom u then !*i2rn u
  45. else if car u eq '!:gi!:
  46. then apply1(get('!:gi!:,'!:crn!:),u)
  47. else apply1(get(car u,'!:rn!:),u);
  48. symbolic procedure mkrn(u,v);
  49. %converts two integers U and V into a rational number, an integer
  50. %or NIL;
  51. if v<0 then mkrn(-u,-v)
  52. else (lambda m; '!:rn!: . ((u/m) . (v/m))) gcdn(u,v);
  53. symbolic procedure !*i2rn u;
  54. %converts integer U to rational number;
  55. '!:rn!: . (u . 1);
  56. symbolic procedure rnminus!: u;
  57. % We must allow for a rational with structured arguments, since
  58. % lowest-terms can produce such objects.
  59. car u . !:minus cadr u . cddr u;
  60. symbolic procedure rnminusp!: u;
  61. % We must allow for a rational with structured arguments, since
  62. % lowest-terms can produce such objects.
  63. if atom (u := cadr u) then u < 0 else apply1(get(car u,'minusp),u);
  64. symbolic procedure rnplus!:(u,v);
  65. mkrn(cadr u*cddr v+cddr u*cadr v,cddr u*cddr v);
  66. symbolic procedure rntimes!:(u,v);
  67. mkrn(cadr u*cadr v,cddr u*cddr v);
  68. symbolic procedure rndifference!:(u,v);
  69. mkrn(cadr u*cddr v-cddr u*cadr v,cddr u*cddr v);
  70. symbolic procedure rnquotient!:(u,v);
  71. mkrn(cadr u*cddr v,cddr u*cadr v);
  72. symbolic procedure rnzerop!: u; cadr u=0;
  73. symbolic procedure rnonep!: u; cadr u=1 and cddr u=1;
  74. symbolic procedure rnfactor!: u;
  75. begin scalar x,y,dmode!*; integer m,n;
  76. x := subf(u,nil);
  77. y := factorf numr x;
  78. n := car y;
  79. dmode!* := '!:rn!:;
  80. y := for each j in cdr y collect
  81. <<n := n*(m := (lnc ckrn car j)**cdr j);
  82. quotfd(car j,m) . cdr j>>;
  83. return int!-equiv!-chk mkrn(n,denr x) . y
  84. end;
  85. symbolic procedure rnprep!: u;
  86. % PREPF is called on arguments, since the LOWEST-TERMS code in extout
  87. % can create rational objects with structured arguments.
  88. (if cddr u=1 then x else list('quotient,x,prepf cddr u))
  89. where x = prepf cadr u;
  90. symbolic procedure rnprin u;
  91. <<prin2!* cadr u; prin2!* "/"; prin2!* cddr u>>;
  92. symbolic procedure rnequiv u;
  93. % Returns an equivalent integer if possible.
  94. if cdr(u := cdr u)=1 then car u else nil;
  95. symbolic procedure rn!:root(u,n);
  96. (if x eq 'failed or y eq 'failed then 'failed else mkrn(x,y))
  97. where x=rootxf(cadr u,n), y=rootxf(cddr u,n);
  98. initdmode 'rational;
  99. endmodule;
  100. end;