mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
287 lines
5.8 KiB
Plaintext
287 lines
5.8 KiB
Plaintext
/*
|
|
* 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 chongo@toad.com
|
|
*
|
|
* 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;
|
|
}
|
|
|
|
global lib_debug;
|
|
if (lib_debug >= 0) {
|
|
print "global defaultverbose defined";
|
|
print "global err defined";
|
|
print "testfrem(x, y, verbose) defined";
|
|
print "testgcdrem(x, y, verbose) defined";
|
|
print "testf(str, n, verbose) defined";
|
|
print "testg(str, n, verbose) defined";
|
|
print "testh(str, n, N, verbose) defined";
|
|
print "test3500(verbose, n, N) defined";
|
|
}
|