/* * test3500 - 3500 series of the regress.cal test suite * * Copyright (C) 1999 Ernest Bowen and Landon Curt Noll * * Primary author: Ernest Bowen * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL. You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * @(#) $Revision: 30.1 $ * @(#) $Id: test3500.cal,v 30.1 2007/03/16 11:09:54 chongo Exp $ * @(#) $Source: /usr/local/src/bin/calc/cal/RCS/test3500.cal,v $ * * Under source code control: 1995/12/18 22:50:46 * File existed as early as: 1995 * * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ */ /* * 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. * */ defaultverbose = 1; /* default verbose value */ 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; }