diff --git a/BUGS b/BUGS index f0fdd98..257af8d 100644 --- a/BUGS +++ b/BUGS @@ -38,18 +38,12 @@ then it may be time to send in a bug report. You can send bug reports to: When you send your report, please include the following information: * a description of the problem - * the version of calc you are using (if you cannot get calc it to run, then send us the 4 #define lines from version.c) - * if you modified calc from an official patch, send me the mods you made - * the type of system you were using - * the type of compiler you were using - * any compiler warnings or errors that you saw - * cd to the calc source directory, and type: make debug > debug.out 2>&1 (sh, ksh, bash users) @@ -112,12 +106,30 @@ Known bugs: =-= -Other items of note: +Problems with known work-a-rounds: * There is a bug in gcc-2.95 that causes calc, when compiled with -O2, to fail the regression test. The work-a-round is to compile with -O or to use gcc-2.96 or later. + * Solaris cc somtimes barfs while compiling zrand.c. In particular, calc + barfs on on the SVAL macro. The work-a-round is to use the Solaric cc + Makefile set sets -DFORCE_STDC. I.e,: + + CCWARN= + CCOPT= ${DEBUG} ${NO_SHARED} + CCMISC= -DFORCE_STDC + # + CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC} + ICFLAGS= ${CCWARN} ${CCMISC} + # + LCFLAGS= + LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} + ILDFLAGS= + # + LCC= cc + CC= ${PURIFY} ${LCC} + * There is a bug in some versions of the Dec/Compaq cc for the Alpha where the following: @@ -156,4 +168,4 @@ Other items of note: * The sparcv9 support for 64 bit Solaris under gcc-2.96 is able to compile calc, but calc dumps core very early on in startup. It is said that sparcv9 support in gcc-2.96 is very unofficial. - There is no work-a-round for this compile problem. + There is no work-a-round for this compiler problem. diff --git a/CHANGES b/CHANGES index 19b0597..3d5d802 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,14 @@ The following are the changes from calc version 2.11.0t10 to date: used in combination with the GNU-readline facility, will prevent it from saving empty lines. + Minor typos fixed in regress.cal + + Added 8500 test serise and test8500.cal to perform more extensive + tests on // and % with various rounding modes. + + The 'unused value ignored' messages now start with Line 999: instead + of just 999:. + The following are the changes from calc version 2.11.0t8.9.1 to 2.11.0t9.4.5: diff --git a/addop.c b/addop.c index 2549d8d..974d382 100644 --- a/addop.c +++ b/addop.c @@ -462,7 +462,8 @@ addop(long op) fp->f_opcodecount -= diff; oldop = OP_NOP; oldoldop = OP_NOP; - fprintf(stderr, "%ld: unused value ignored\n", + fprintf(stderr, + "Line %ld: unused value ignored\n", linenumber()); return; } diff --git a/lib/Makefile b/lib/Makefile index 7a589e0..3d94123 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -44,7 +44,8 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \ test2700.cal test3100.cal test3300.cal test3400.cal prompt.cal \ test3500.cal seedrandom.cal test4000.cal test4100.cal test4600.cal \ beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \ - randomrun.cal xx_print.cal natnumset.cal qtime.cal test8400.cal + randomrun.cal xx_print.cal natnumset.cal qtime.cal test8400.cal \ + test8500.cal # These files are found (but not built) in the distribution # diff --git a/lib/regress.cal b/lib/regress.cal index 8f06200..f5a9f1e 100644 --- a/lib/regress.cal +++ b/lib/regress.cal @@ -7389,8 +7389,8 @@ X5800 = obj xy5800 = {1,2}; print '5864: X5800 = obj xy5800 = {1,2}'; vrfy(X5800 == (obj xy5800 = {1,2}), '5865: X5800 == (obj xy5800 = {1,2})'); -define f5800(a8500 = mat[2] = {3,4}) = 5 * a8500; -print '5866: define f5800(a8500 = mat[2] = {3,4}) = 5 * a8500;' +define f5800(a5800 = mat[2] = {3,4}) = 5 * a5800; +print '5866: define f5800(a5800 = mat[2] = {3,4}) = 5 * a5800;' vrfy(f5800() == (mat[] = {15,20}),'5867: f5800() == (mat[] = {15,20})'); print '5868: End of 5800 sequence'; @@ -7493,6 +7493,15 @@ vrfy(test8400() == 64434, '8405: test8400() == 64434'); print '8406: Ending test_quit'; +/* + * test_divmod - psuedo-random tests on the // and % with various rounding modes + */ +print; +print '8500: Starting test_divmod' +read -once "test8500"; +/* 85xx: Ending test_divmod is printed by test8500.cal */ + + /* * read various calc libs * diff --git a/lib/test8500.cal b/lib/test8500.cal new file mode 100644 index 0000000..3e28ed9 --- /dev/null +++ b/lib/test8500.cal @@ -0,0 +1,242 @@ +/* + * 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 8500 series of the regress.cal test suite. + */ +/* + * Tests of // and % operators + */ + +global err_8500; /* divmod_8500 error count */ +global L_8500; /* list of problem values */ +global ver_8500; /* test verbosity - see setting comment near bottom */ +global old_seed_8500; /* old srand() seed */ + +/* + * save the config state so that we can change it and restore later + */ +global cfg_8500 = config("all"); + + +/* + * onetest_8500 - perform one division / remainder test + * + * Returns: + * 0 = test was successful + * >0 = test error indicator + */ +define onetest_8500(a,b,rnd) { + local q, r, s, S; + + /* + * set a random rounding mode + */ + config("quo", rnd), config("mod", rnd); + + /* + * perform the division and mod + */ + q = a // b; + r = a % b; + + /* + * verify the fundamental math + */ + if (a != q * b + r) + return 1; + + /* + * determine if the rounding worked + */ + if (b) { + if (rnd & 16) + s = sgn(abs(r) - abs(b)/2); + else + s = sgn(abs(r) - abs(b)); + + if (s < 0 || r == 0) + return 0; + + if (s > 0) + return 2; + + if (((rnd & 16) && s == 0) || !(rnd & 16)) { + + S = sgn(r) * sgn(b); /* This is sgn(a/b) - a//b */ + switch (rnd & 15) { + case 0: return (S < 0) ? 3 : 0; + case 1: return (S > 0) ? 4 : 0; + case 2: return (S != sgn(a)*sgn(b)) ? 5 : 0; + case 3: return (S != -sgn(a)*sgn(b)) ? 6 : 0; + break; + case 4: return (S != sgn(b)) ? 7 : 0; + case 5: return (S != -sgn(b)) ? 8 : 0; + case 6: return (S != sgn(a)) ? 9 : 0; + case 7: return (S != -sgn(a)) ? 10 : 0; + case 8: return (isodd(q)) ? 11 : 0; + case 9: return (iseven(q)) ? 12 : 0; + case 10: return (iseven(q) != (a/b > 0)) ? 13:0; + case 11: return (isodd(q) != (a/b > 0)) ? 14:0; + case 12: return (iseven(q) != (b > 0)) ? 15 : 0; + case 13: return (isodd(q) != (b > 0)) ? 16 : 0; + case 14: return (iseven(q) != (a > 0)) ? 17 : 0; + case 15: return (isodd(q) != (a > 0)) ? 18 : 0; + } + } + } + + /* + * all is well + */ + return 0; +} + + +/* + * divmod_8500 - perform a bunch of pseudo-random // and % test + * + * divmod_8500(N, M1, M2) will perform N tests with randomly chosen integers + * a, b with abs(a) < M1, abs(b) < M2, which with 50% probability are + * converted to a = (2 * a + 1) * b, b = 2 * b (to give case where + * a / b is an integer + 1/2). + * + * N defaults to 10, M1 to 2^128, M2 to 2^64 + * + * The testnum, if > 0, is used while printing a failure or success. + * + * The rounding parameter is randomly chosen. + * + * After a run of divmod_8500 the a, b, rnd values which gave failure are + * stored in the list L_8500. L_8500[0], L_8500[1], L_8500[2] are a, b, rnd for the first + * test, etc. + */ +define divmod_8500(N = 10, M1 = 2^128, M2 = 2^64, testnum = 0) +{ + local a, b, i, v, rnd; + local errmsg; /* error message to display */ + + /* + * firewall + */ + if (!isint(M1) || M1 < 2) + quit "Bad second arg for dtest"; + + if (!isint(M2) || M2 < 2) + quit "Bad third arg for dtest"; + + /* + * test setup + */ + err_8500 = 0; + L_8500 = list(); + + /* + * perform the random results + */ + for (i = 0; i < N; i++) { + + /* + * randomly select two values in the range controlled by M1,M2 + */ + a = rand(-M1+1, M1); + b = rand(-M2+1, M2); + if (rand(2)) { + a = (2 * a + 1) * b; + b *= 2; + } + + /* + * seelect one of the 32 rounding modes at random + */ + rnd = rand(32); + + /* + * ver_8500 pre-test reporting + */ + if (ver_8500 > 1) + printf("Test %d: a = %d, b = %d, rnd = %d\n", + i, a, b, rnd); + + /* + * perform the actual test + */ + v = onetest_8500(a, b, rnd); + + /* + * individual test analysis + */ + if (v != 0) { + err_8500++; + if (ver_8500 != 0) { + if (testnum > 0) { + errmsg = strprintf( + "Failure %d on test %d", v, i); + prob(errmsg); + } else { + printf("Failure %d on test %d", v, i); + } + } + append(L_8500, a, b, rnd); + } + } + + /* + * report in the results + */ + if (err_8500) { + if (testnum > 0) { + errmsg = strprintf( + "%d: divmod_8500(%d,,,%d): %d failures", + testnum, N, testnum, err_8500); + prob(errmsg); + } else { + printf("%s failure%s", err_8500, + (err_8500 > 1) ? "s" : ""); + } + } else { + if (testnum > 0) { + errmsg = strprintf("%d: divmod_8500(%d,,,%d)", + testnum, N, testnum); + vrfy(err_8500 == 0, errmsg); + } else { + print "No failure"; + } + } +} + +/* + * ver_8500 != 0 displays failures; ver_8500 > 1 displays all numbers tested + */ +ver_8500 = 0; +print '8501: ver_8500 = 0'; +old_seed_8500 = srand(31^61); +print '8502: old_seed_8500 = srand(31^61)'; + +/* + * do the tests + */ +divmod_8500(250, 2^128, 2^1, 8503); +divmod_8500(250, 2^128, 2^64, 8504); +divmod_8500(250, 2^256, 2^64, 8505); +divmod_8500(250, 2^1024, 2^64, 8506); +divmod_8500(250, 2^1024, 2^128, 8507); +divmod_8500(250, 2^16384, 2^1024, 8508); +divmod_8500(1000, 2^128, 2^64, 8509); + +/* + * restore state + */ +config("all", cfg_8500),; +print '8510: config("all", cfg_8500),'; +srand(old_seed_8500),; +print '8511: srand(old_seed_8500),'; + +/* + * finished with 8500 tests + */ +print '8512: Ending test_divmod'; diff --git a/version.c b/version.c index 048d756..2c29ee7 100644 --- a/version.c +++ b/version.c @@ -18,7 +18,7 @@ static char *program; #define MAJOR_VER 2 /* major version */ #define MINOR_VER 11 /* minor version */ #define MAJOR_PATCH 0 /* patch level or 0 if no patch */ -#define MINOR_PATCH "10.1.1" /* test number or empty string if no patch */ +#define MINOR_PATCH "10.1.2" /* test number or empty string if no patch */ /* * calc version constants