2 * test2600 - 2600 series of the regress.cal test suite
4 * Copyright (C) 1999 Ernest Bowen and Landon Curt Noll
6 * Primary author: Ernest Bowen
8 * Calc is open software; you can redistribute it and/or modify it under
9 * the terms of the version 2.1 of the GNU Lesser General Public License
10 * as published by the Free Software Foundation.
12 * Calc is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
15 * Public License for more details.
17 * A copy of version 2.1 of the GNU Lesser General Public License is
18 * distributed with calc under the filename COPYING-LGPL. You should have
19 * received a copy with calc; if not, write to Free Software Foundation, Inc.
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * @(#) $Revision: 30.3 $
23 * @(#) $Id: test2600.cal,v 30.3 2013/08/11 08:41:38 chongo Exp $
24 * @(#) $Source: /usr/local/src/bin/calc/cal/RCS/test2600.cal,v $
26 * Under source code control: 1995/10/13 00:13:14
27 * File existed as early as: 1995
29 * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
33 * Stringent tests of some of calc's builtin functions.
34 * Most of the tests are concerned with the accuracy of the value
35 * returned for a function; usually it is expected that
36 * remainder (true value - calculated value) will be less in
37 * absolute value than "epsilon", where this is either a specified
38 * argument eps, or if this is omitted, the current value of epsilon().
39 * In some cases the remainder is to have a particular sign, or to
40 * have absolute value not exceeding eps/2, or in some cases 3 * eps/4.
42 * Typical of these tests is testpower("power", n, b, eps, verbose).
43 * Here n is the number of numbers a for which power(a, b, eps) is to
44 * be evaluated; the ratio c = (true value - calculated value)/eps
45 * is calculated and if this is not less in absolute value than
46 * 0.75, a "failure" is recorded and the value of a displayed.
47 * On completion of the tests, the minimum and maximum values of
50 * The numbers a are usually large "random" integers or sometimes
51 * ratios of such integers. In some cases the formulae used to
52 * calculate c assume eps is small compared with the value of the
53 * function. If eps is very small, say 1e-1000, or if the denominator
54 * of b in power(a, b, eps) is large, the computation required for
55 * a test may be very heavy.
57 * Test funcations are called as:
59 * testabc(str, ..., verbose)
61 * where str is a string that names the test. This string is printed
62 * without a newline (if verbose > 0), near the beginning of the function.
63 * The verbose parameter controls how verbose the test will be:
66 * 1 - print str and the error count
67 * 2 - print min and max errors as well
68 * 3 - print everything including individual loop counts
70 * All functions return the number of errors that they detected.
74 global defaultverbose = 1; /* default verbose value */
77 define testismult(str, n, verbose)
81 if (isnull(verbose)) verbose = defaultverbose;
86 for (i = 0; i < n; i++) {
87 if (verbose > 2) print i,:;
88 a = scale(rand(1,1e1000), rand(100));
89 b = scale(rand(1,1e1000), rand(100));
94 printf("*** Failure with:\na = %d\nb = %d\n",
101 printf("*** %d error(s)\n", m);
103 printf("no errors\n");
109 define testsqrt(str, n, eps, verbose)
111 local a, c, i, x, m, min, max;
113 if (isnull(verbose)) verbose = 2;
122 for (i = 1; i <= n; i++) {
123 if (verbose > 2) print i,:;
124 a = scale(rand(1,1000), rand(100));
137 printf("*** Failure with:\na = %d\neps = %d\n",
144 printf("*** %d error(s)\n", m);
145 printf(" %s: rem/eps min=%d, max=%d\n",
148 printf("no errors\n");
152 printf(" %s: rem/eps min=%0.4d, max=%0.4d\n", str, min, max);
158 define testexp(str, n, eps, verbose)
160 local i, a, c, m, min, max;
162 if (isnull(verbose)) verbose = 2;
170 for (i = 1; i <= n; i++) {
171 if (verbose > 2) print i,:;
172 a = rand(1,1e20)/rand(1,1e20) + rand(50);
183 printf("*** Failure with:\na = %d\neps = %d\n",
190 printf("*** %d error(s)\n", m);
191 printf(" %s: rem/eps min=%d, max=%d\n",
194 printf("no errors\n");
198 printf(" %s: rem/eps min=%0.4d, max=%0.4d\n", str, min, max);
204 define cexp(x,eps) /* Find relative rem/eps for exp(x, eps) */
206 local eps1, v, v1, c;
213 c = round((v1 - v)/v1/eps, 6, 24);
218 define testln(str, n, eps, verbose)
220 local i, a, c, m, min, max;
222 if (isnull(verbose)) verbose = 2;
230 for (i = 1; i <= n; i++) {
231 if (verbose > 2) print i,:;
232 a = rand(1,1e20)/rand(1,1e20) + rand(50);
241 printf("*** Failure with:\na = %d\neps = %d\n",
248 printf("*** %d error(s)\n", m);
249 printf(" %s: rem/eps min=%d, max=%d\n",
252 printf("no errors\n");
256 printf(" %s: rem/eps min=%0.4d, max=%0.4d\n", str, min, max);
263 local eps1, v, v1, c;
270 c = round((v1 - v)/eps, 6, 24);
275 define testpower(str, n, b, eps, verbose)
277 local i, a, c, m, min, max;
279 if (isnull(verbose)) verbose = 2;
286 quit "Second argument (exponent) to be a number";
289 for (i = 1; i <= n; i++) {
290 if (verbose > 2) print i,:;
291 a = rand(1,1e20)/rand(1,1e20);
296 printf("*** Failure for a = %d\n", a);
306 printf("*** %d error(s)\n", m);
307 printf(" %s: rem/eps min=%d, max=%d\n",
310 printf("no errors\n");
314 printf(" %s: rem/eps min=%0.4d, max=%0.4d\n", str, min, max);
320 define testpower2(str, n, eps, verbose)
322 local i, a, c, m, min, max;
328 if (isnull(verbose)) verbose = 2;
334 oldeps = epsilon(eps);
337 quit "Second argument (exponent) to be a number";
340 for (i = 1; i <= n; i++) {
341 if (verbose > 2) print i,:;
345 a = a / (int(a/2)+rand(1,1e20));
347 b = b / (int(b/2)+rand(1,1e20));
353 printf("*** real^real failure for a = %d\n", a);
359 a = a / (int(a/2)+rand(1,1e20));
361 b = b / (int(b/2)+rand(1,1e20));
367 printf("*** comp^real failure for a = %d\n", a);
373 a = a / (int(a/2)+rand(1,1e20));
375 b = b / (int(b/2)+rand(1,1e20));
381 printf("*** real^comp failure for a = %d\n", a);
385 /* complex ^ complex */
387 a = a / (int(a/2)+rand(1,1e20));
389 b = b / (int(b/2)+rand(1,1e20));
391 c2 = power(a*1i, b*1i);
395 printf("*** comp^comp failure for a = %d\n", a);
402 printf("*** %d error(s)\n", m);
403 printf(" %s: rem/eps min=%d, max=%d\n",
406 printf("no errors\n");
410 printf(" %s: rem/eps min=%0.4d, max=%0.4d\n", str, min, max);
416 define cpow(a, b, eps) /* Find rem/eps for power(a,b,eps) */
418 local v, v1, c, n, d, h;
425 v = power(a, b, eps);
426 h = (a^n/v^d - 1) * v/d;
427 c = round(h/eps, 6, 24);
431 define testgcd(str, n, verbose)
435 if (isnull(verbose)) verbose = 2;
440 for (i = 1; i <= n; i++) {
441 if (verbose > 2) print i,:;
445 if (!ismult(a,g) || !ismult(b,g) || !g || !isrel(a/g, b/g)) {
447 printf("*** Failure for a = %d, b = %d\n", a, b);
452 printf("*** %d error(s)\n", m);
454 printf("no errors\n");
460 define mkreal() = scale(rand(-1000,1001)/rand(1,1000), rand(-100, 101));
462 define mkcomplex() = mkreal() + 1i * mkreal();
468 x = rand(100, 1000)/rand(1,10);
474 define mksmallreal() = rand(-10, 11)/rand(100,1000);
476 define testappr(str, n, verbose)
478 local x, y, z, m, i, p;
481 verbose = defaultverbose;
486 for (i = 1; i <= n; i++) {
487 x = rand(3) ? mkreal(): mkcomplex();
490 printf(" %d: x = %d, y = %d\n", i, x, y);
492 for (z = 0; z < 32; z++) {
493 p = checkappr(x,y,z,verbose);
495 printf("*** Failure for x=%d, y=%d, z=%d\n",
503 printf("*** %d error(s)\n", m);
505 printf("no errors\n");
512 define checkappr(x,y,z,verbose) /* Returns 1 if an error is detected */
518 printf("\ta = %d\n", a);
520 return checkresult(x,y,z,a);
522 return checkresult(re(x), y, z, re(a))
523 | checkresult(im(x), y, z, im(a));
525 quit "Bad first argument for checkappr()";
528 define checkresult(x,y,z,a) /* tests correctness of a = appr(x,y,z) */
539 if (abs(r) >= abs(y))
544 if (abs(r) > abs(y)/2)
546 if (abs(r) < abs(y)/2)
552 case 0: v = (s == sgn(y)); break;
553 case 1: v = (s == -sgn(y)); break;
554 case 2: v = (s == sgn(x)); break;
555 case 3: v = (s == -sgn(x)); break;
556 case 4: v = (s > 0); break;
557 case 5: v = (s < 0); break;
558 case 6: v = (s == sgn(x/y)); break;
559 case 7: v = (s == -sgn(x/y)); break;
560 case 8: v = iseven(n); break;
561 case 9: v = isodd(n); break;
562 case 10: v = (x/y > 0) ? iseven(n) : isodd(n); break;
563 case 11: v = (x/y > 0) ? isodd(n) : iseven(n); break;
564 case 12: v = (y > 0) ? iseven(n) : isodd(n); break;
565 case 13: v = (y > 0) ? isodd(n) : iseven(n); break;
566 case 14: v = (x > 0) ? iseven(n) : isodd(n); break;
567 case 15: v = (x > 0) ? isodd(n) : iseven(n); break;
573 * test2600 - perform all of the above tests a bunch of times
575 define test2600(verbose, tnum)
577 local n; /* test parameter */
578 local ep; /* test parameter */
581 /* set test parameters */
582 n = 5; /* internal test loop count */
583 if (isnull(verbose)) {
584 verbose = defaultverbose;
587 tnum = 1; /* initial test number */
591 * test a lot of stuff
595 err += testismult(strcat(str(tnum++), ": mult"), n*20, verbose);
596 err += testappr(strcat(str(tnum++), ": appr"), n*40, verbose);
597 err += testexp(strcat(str(tnum++),": exp"), n, ep, verbose);
598 err += testln(strcat(str(tnum++),": ln"), n, ep, verbose);
599 err += testpower(strcat(str(tnum++),": power"), n,
600 rand(2,10), ep, verbose);
601 err += testgcd(strcat(str(tnum++),": gcd"), n, ep, verbose);
602 for (i=0; i < 32; ++i) {
604 err += testsqrt(strcat(str(tnum++),": sqrt",str(i)), n*10,
607 err += testpower2(strcat(str(tnum++),": power"), n*4, ep, verbose);
610 print "***", err, "error(s) found in test2600";
612 print "no errors in test2600";