/* * Copyright (c) 1996 Ernest Bowen and Landon Curt Noll * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * * By: Ernest Bowen and Landon Curt Noll * ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/ * * This library is used by the 3500 series of the regress.cal test suite. */ /* * Stringent tests of the functions frem, fcnt, gcdrem. * * testf(n) gives n tests of frem(x,y) and fcnt(x,y) with randomly * integers x and y generated so that x = f * y^k where f, y and * k are randomly generated. * * testg(n) gives n tests of gcdrem(x,y) with x and y generated as for * testf(n). * * testh(n,N) gives n tests of g = gcdrem(x,y) where x and y are products of * powers of small primes some of which are common to both x and y. * This test uses f = abs(x) and iteratively f = frem(f,p) where * p varies over the prime divisors of y; the final value for f * should equal g. For both x and y the primes are raised to the * power rand(N); N defaults to 10. * * If verbose is > 1, the numbers x, y and values for some of the * functions will be displayed. Numbers used in testf() * and testg() occasionally have thousands of digits. * */ global defaultverbose = 1; /* default verbose value */ global err; define testfrem(x,y,verbose) { local f, n; if (isnull(verbose)) verbose = defaultverbose; f = frem(x,y); n = fcnt(x,y); if (verbose > 1) printf("frem = %d, fcnt = %d\n\n", f, n); if (abs(x) != f * abs(y)^n) return 1; if (!ismult(x,y) || abs(y) <= 1) { if (f != abs(x)) return 2; if (n != 0) return 3; return 0; } if (x == 0) { if (f != 0 || n != 0) return 4; return 0; } if (f < 0 || !isint(f) || n <= 0) return 5; if (ismult(f, y)) return 6; if (!ismult(x, y^n)) return 7; if (ismult(x, y^(n+1))) return 8; return 0; } define testgcdrem(x,y,verbose) { local d, q; if (isnull(verbose)) verbose = defaultverbose; d = gcdrem(x,y); if (verbose > 1) printf("gcdrem = %d\n\n", d); if (y == 0) { if (d != 1) return 1; return 0; } if (x == 0) { if (d != 0) return 2; return 0; } if (d <= 0) return 3; q = x/d; if (!isint(q)) return 4; if (!isrel(d, y)) return 5; if (!isrel(d, q)) return 6; return 0; } define testf(str,n,verbose) { local m, x, y, i, k, y1, f1, f, fail; if (isnull(verbose)) verbose = defaultverbose; if (verbose > 0) { print str:":",:; } m = 0; for (i = 0; i < n; i++) { y1 = rand(2^rand(1,6)); y = rand(-(2^y1), 1 + 2^y1); f1 = rand(2^rand(1,11)); f = rand(-(2^f1), 1+2^f1); k = rand(1,1+2^10); x = f * y^k; if (verbose > 1) { printf("x = %d\n", x); printf("y = %d\n", y); } fail = testfrem(x,y,verbose); if (fail != 0) { printf("*** Failure %d on loop %d\n", fail, i); if (verbose > 1) { printf(" x = %d\n", x); printf(" y = %d\n", y); } m++; } } if (verbose > 0) { if (m) { printf("*** %d error(s)\n", m); } else { printf("no errors\n"); } } return m; } define testg(str,n,verbose) { local m, x, y, i, k, y1, f1, f, fail; if (isnull(verbose)) verbose = defaultverbose; if (verbose > 0) { print str:":",:; } m = 0; for (i = 0; i < n; i++) { y1 = rand(2^rand(1,6)); y = rand(-(2^y1), 1 + 2^y1); f1 = rand(2^rand(1,11)); f = rand(-(2^f1), 1+2^f1); k = rand(1,1+2^10); x = f * y^k; if (verbose > 1) { printf("x = %d\n", x); printf("y = %d\n", y); } fail = testgcdrem(x,y,verbose); if (fail != 0) { printf("*** Failure %d on loop %d\n", fail, i); if (verbose > 1) { printf(" x = %d\n", x); printf(" y = %d\n", y); } m++; } } if (verbose > 0) { if (m) { printf("*** %d error(s)\n", m); } else { printf("no errors\n"); } } return m; } define testh(str,n,N,verbose) { local m, i, x, y, f, g; if (isnull(verbose)) verbose = defaultverbose; if (verbose > 0) { print str:":",:; } m = 0; if (isnull(N)) N = 61; for (i = 0; i < n; i ++) { x = 2^rand(N)*3^rand(N) * 7^rand(N) * 11^rand(N) * 101^rand(N); y = 2^rand(N) * 3^rand(N) * 5^rand(N) * 11^rand(N) * 53^rand(N); if (rand(2)) x = -x; if (rand(2)) y = -y; if (verbose > 1) { printf("x = %d\n", x); printf("y = %d\n", y); } f = abs(x); g = gcdrem(x,y); if (ismult(y,2)) f = frem(f,2); if (ismult(y,3)) f = frem(f,3); if (ismult(y,5)) f = frem(f,5); if (ismult(y,11)) f = frem(f,11); if (ismult(y,53)) f = frem(f,53); if (f != g) { printf("*** Failure on loop %d\n", i); if (verbose > 1) { printf(" x = %d\n", x); printf(" y = %d\n", y); printf(" f = %d\n", f); printf(" g = %d\n", g); } m++; } } if (verbose > 0) { if (m) { printf("*** %d error(s)\n", m); } else { printf("no errors\n"); } } return m; } /* * test3500 - perform all of the above tests a bunch of times */ define test3500(verbose, tnum, n, N) { /* set test parameters */ if (isnull(verbose)) { verbose = defaultverbose; } if (isnull(tnum)) { tnum = 3501; /* default test number */ } if (isnull(n)) { n = 200; } if (isnull(N)) { N = 61; } /* * test a lot of stuff */ srand(3500e3500); err += testf(strcat(str(tnum++), ": frem/fcnt"), n, verbose); err += testg(strcat(str(tnum++), ": gcdrem"), n, verbose); err += testh(strcat(str(tnum++),": gcdrem #2"), n, N, verbose); if (verbose > 1) { if (err) { print "***", err, "error(s) found in testall"; } else { print "no errors in testall"; } } return tnum; }