123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- module rational; % *** Tables for rational numbers ***.
- % Author: Anthony C. Hearn.
- % Copyright (c) 1987 The RAND Corporation. All rights reserved.
- global '(domainlist!*);
- switch rational;
- domainlist!* := union('(!:rn!:),domainlist!*);
- put('rational,'tag,'!:rn!:);
- put('!:rn!:,'dname,'rational);
- flag('(!:rn!:),'field);
- put('!:rn!:,'i2d,'!*i2rn);
- put('!:rn!:,'!:ft!:,'!*rn2ft);
- put('!:rn!:,'minus,'rnminus!:);
- put('!:rn!:,'minusp,'rnminusp!:);
- put('!:rn!:,'plus,'rnplus!:);
- put('!:rn!:,'times,'rntimes!:);
- put('!:rn!:,'difference,'rndifference!:);
- put('!:rn!:,'quotient,'rnquotient!:);
- put('!:rn!:,'zerop,'rnzerop!:);
- put('!:rn!:,'onep,'rnonep!:);
- put('!:rn!:,'factorfn,'rnfactor!:);
- put('!:rn!:,'expt,'rnexpt!:);
- put('!:rn!:,'prepfn,'rnprep!:);
- put('!:rn!:,'prifn,'rnprin);
- put('!:rn!:,'intequivfn,'rnequiv);
- put('!:rn!:,'rootfn,'rn!:root);
- flag('(!:rn!:),'ratmode);
- symbolic procedure rnexpt!:(u,n);
- % U is a tagged rational number, n an integer.
- begin scalar v;
- if n=0 then return 1;
- v:=cdr u;
- if (n<0) then <<
- n:=-n;
- if (car v < 0) then
- v:= (- cdr v) . (- car v)
- else v:= (cdr v) . (car v) >>;
- if (n=1) then return (car u) . v;
- return (car u) . ((car v ** n) . (cdr v ** n));
- % No more cancellation can take place in this exponentiation.
- end;
- symbolic procedure mkratnum u;
- % U is a domain element. Value is equivalent real or complex
- % rational number.
- if atom u then !*i2rn u
- else if car u eq '!:gi!:
- then apply1(get('!:gi!:,'!:crn!:),u)
- else apply1(get(car u,'!:rn!:),u);
- symbolic procedure mkrn(u,v);
- %converts two integers U and V into a rational number, an integer
- %or NIL;
- if v<0 then mkrn(-u,-v)
- else (lambda m; '!:rn!: . ((u/m) . (v/m))) gcdn(u,v);
- symbolic procedure !*i2rn u;
- %converts integer U to rational number;
- '!:rn!: . (u . 1);
- symbolic procedure rnminus!: u;
- % We must allow for a rational with structured arguments, since
- % lowest-terms can produce such objects.
- car u . !:minus cadr u . cddr u;
- symbolic procedure rnminusp!: u;
- % We must allow for a rational with structured arguments, since
- % lowest-terms can produce such objects.
- if atom (u := cadr u) then u < 0 else apply1(get(car u,'minusp),u);
- symbolic procedure rnplus!:(u,v);
- mkrn(cadr u*cddr v+cddr u*cadr v,cddr u*cddr v);
- symbolic procedure rntimes!:(u,v);
- mkrn(cadr u*cadr v,cddr u*cddr v);
- symbolic procedure rndifference!:(u,v);
- mkrn(cadr u*cddr v-cddr u*cadr v,cddr u*cddr v);
- symbolic procedure rnquotient!:(u,v);
- mkrn(cadr u*cddr v,cddr u*cadr v);
- symbolic procedure rnzerop!: u; cadr u=0;
- symbolic procedure rnonep!: u; cadr u=1 and cddr u=1;
- symbolic procedure rnfactor!: u;
- begin scalar x,y,dmode!*; integer m,n;
- x := subf(u,nil);
- y := factorf numr x;
- n := car y;
- dmode!* := '!:rn!:;
- y := for each j in cdr y collect
- <<n := n*(m := (lnc ckrn car j)**cdr j);
- quotfd(car j,m) . cdr j>>;
- return int!-equiv!-chk mkrn(n,denr x) . y
- end;
- symbolic procedure rnprep!: u;
- % PREPF is called on arguments, since the LOWEST-TERMS code in extout
- % can create rational objects with structured arguments.
- (if cddr u=1 then x else list('quotient,x,prepf cddr u))
- where x = prepf cadr u;
- symbolic procedure rnprin u;
- <<prin2!* cadr u; prin2!* "/"; prin2!* cddr u>>;
- symbolic procedure rnequiv u;
- % Returns an equivalent integer if possible.
- if cdr(u := cdr u)=1 then car u else nil;
- symbolic procedure rn!:root(u,n);
- (if x eq 'failed or y eq 'failed then 'failed else mkrn(x,y))
- where x=rootxf(cadr u,n), y=rootxf(cddr u,n);
- initdmode 'rational;
- endmodule;
- end;
|