123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- #include "stdafx.h"
- #include "defs.h"
- void
- eval_gcd(void)
- {
- p1 = cdr(p1);
- push(car(p1));
- eval();
- p1 = cdr(p1);
- while (iscons(p1)) {
- push(car(p1));
- eval();
- gcd();
- p1 = cdr(p1);
- }
- }
- void
- gcd(void)
- {
- int x = expanding;
- save();
- gcd_main();
- restore();
- expanding = x;
- }
- void
- gcd_main(void)
- {
- expanding = 1;
- p2 = pop();
- p1 = pop();
- if (equal(p1, p2)) {
- push(p1);
- return;
- }
- if (isrational(p1) && isrational(p2)) {
- push(p1);
- push(p2);
- gcd_numbers();
- return;
- }
- if (car(p1) == symbol(ADD) && car(p2) == symbol(ADD)) {
- gcd_expr_expr();
- return;
- }
- if (car(p1) == symbol(ADD)) {
- gcd_expr(p1);
- p1 = pop();
- }
- if (car(p2) == symbol(ADD)) {
- gcd_expr(p2);
- p2 = pop();
- }
- if (car(p1) == symbol(MULTIPLY) && car(p2) == symbol(MULTIPLY)) {
- gcd_term_term();
- return;
- }
- if (car(p1) == symbol(MULTIPLY)) {
- gcd_term_factor();
- return;
- }
- if (car(p2) == symbol(MULTIPLY)) {
- gcd_factor_term();
- return;
- }
-
- if (car(p1) == symbol(POWER)) {
- p3 = caddr(p1);
- p1 = cadr(p1);
- } else
- p3 = one;
- if (car(p2) == symbol(POWER)) {
- p4 = caddr(p2);
- p2 = cadr(p2);
- } else
- p4 = one;
- if (!equal(p1, p2)) {
- push(one);
- return;
- }
-
- if (isnum(p3) && isnum(p4)) {
- push(p1);
- if (lessp(p3, p4))
- push(p3);
- else
- push(p4);
- power();
- return;
- }
-
- push(p3);
- push(p4);
- divide();
- p5 = pop();
- if (isnum(p5)) {
- push(p1);
-
- if (car(p3) == symbol(MULTIPLY) && isnum(cadr(p3)))
- p5 = cadr(p3);
- else
- p5 = one;
- if (car(p4) == symbol(MULTIPLY) && isnum(cadr(p4)))
- p6 = cadr(p4);
- else
- p6 = one;
- if (lessp(p5, p6))
- push(p3);
- else
- push(p4);
- power();
- return;
- }
- push(p3);
- push(p4);
- subtract();
- p5 = pop();
- if (!isnum(p5)) {
- push(one);
- return;
- }
-
- push(p1);
- if (isnegativenumber(p5))
- push(p3);
- else
- push(p4);
- power();
- }
- void
- gcd_expr_expr(void)
- {
- if (length(p1) != length(p2)) {
- push(one);
- return;
- }
- p3 = cdr(p1);
- push(car(p3));
- p3 = cdr(p3);
- while (iscons(p3)) {
- push(car(p3));
- gcd();
- p3 = cdr(p3);
- }
- p3 = pop();
- p4 = cdr(p2);
- push(car(p4));
- p4 = cdr(p4);
- while (iscons(p4)) {
- push(car(p4));
- gcd();
- p4 = cdr(p4);
- }
- p4 = pop();
- push(p1);
- push(p3);
- divide();
- p5 = pop();
- push(p2);
- push(p4);
- divide();
- p6 = pop();
- if (equal(p5, p6)) {
- push(p5);
- push(p3);
- push(p4);
- gcd();
- multiply();
- } else
- push(one);
- }
- void
- gcd_expr(U *p)
- {
- p = cdr(p);
- push(car(p));
- p = cdr(p);
- while (iscons(p)) {
- push(car(p));
- gcd();
- p = cdr(p);
- }
- }
- void
- gcd_term_term(void)
- {
- push(one);
- p3 = cdr(p1);
- while (iscons(p3)) {
- p4 = cdr(p2);
- while (iscons(p4)) {
- push(car(p3));
- push(car(p4));
- gcd();
- multiply();
- p4 = cdr(p4);
- }
- p3 = cdr(p3);
- }
- }
- void
- gcd_term_factor(void)
- {
- push(one);
- p3 = cdr(p1);
- while (iscons(p3)) {
- push(car(p3));
- push(p2);
- gcd();
- multiply();
- p3 = cdr(p3);
- }
- }
- void
- gcd_factor_term(void)
- {
- push(one);
- p4 = cdr(p2);
- while (iscons(p4)) {
- push(p1);
- push(car(p4));
- gcd();
- multiply();
- p4 = cdr(p4);
- }
- }
- #if SELFTEST
- static char *s[] = {
- "gcd(30,42)",
- "6",
- "gcd(42,30)",
- "6",
- "gcd(-30,42)",
- "6",
- "gcd(42,-30)",
- "6",
- "gcd(30,-42)",
- "6",
- "gcd(-42,30)",
- "6",
- "gcd(-30,-42)",
- "6",
- "gcd(-42,-30)",
- "6",
- "gcd(x,x)",
- "x",
- "gcd(-x,x)",
- "x",
- "gcd(x,-x)",
- "x",
- "gcd(-x,-x)",
- "-x",
- "gcd(x^2,x^3)",
- "x^2",
- "gcd(x,y)",
- "1",
- "gcd(y,x)",
- "1",
- "gcd(x*y,y)",
- "y",
- "gcd(x*y,y^2)",
- "y",
- "gcd(x^2*y^2,x^3*y^3)",
- "x^2*y^2",
- "gcd(x^2,x^3)",
- "x^2",
-
- "gcd(x+y,x+z)",
- "1",
- "gcd(x+y,x+y)",
- "x+y",
- "gcd(x+y,2*x+2*y)",
- "x+y",
- "gcd(-x-y,x+y)",
- "x+y",
- "gcd(4*x+4*y,6*x+6*y)",
- "2*x+2*y",
- "gcd(4*x+4*y+4,6*x+6*y+6)",
- "2+2*x+2*y",
- "gcd(4*x+4*y+4,6*x+6*y+12)",
- "1",
- "gcd(27*t^3+y^3+9*t*y^2+27*t^2*y,t+y)",
- "1",
-
- "gcd(2*a^2*x^2+a*x+a*b,a)",
- "a",
- "gcd(2*a^2*x^2+a*x+a*b,a^2)",
- "a",
- "gcd(2*a^2*x^2+2*a*x+2*a*b,a)",
- "a",
-
- "gcd(2*a^2*x^2+2*a*x+2*a*b,2*a)",
- "2*a",
- "gcd(2*a^2*x^2+2*a*x+2*a*b,3*a)",
- "a",
- "gcd(2*a^2*x^2+2*a*x+2*a*b,4*a)",
- "2*a",
-
- "gcd(x,x^2)",
- "x",
- "gcd(x,x^a)",
- "1",
-
- "gcd(12,18,9)",
- "3",
- };
- void
- test_gcd(void)
- {
- test(__FILE__, s, sizeof s / sizeof (char *));
- }
- #endif
|