From bd3086138beaafe98afc65e5ce8fee3a00e4ba6c Mon Sep 17 00:00:00 2001 From: Landon Curt Noll Date: Sun, 11 Jun 2006 00:54:41 -0700 Subject: [PATCH] Release calc version 2.12.0.3 --- CHANGES | 349 +++++++----- cal/Makefile | 6 +- cal/README | 72 ++- cal/alg_config.cal | 1253 ++++++++++++++++++++++++++++++++++++++++++++ cal/regress.cal | 112 +++- cal/test4100.cal | 10 +- codegen.c | 20 +- config.c | 111 ++-- config.h | 6 +- func.c | 6 +- hash.c | 5 +- help/address | 28 +- help/blkcpy | 57 +- help/calc_tty | 12 +- help/command | 296 ++++++----- help/config | 195 ++++++- help/define | 56 +- help/dereference | 19 +- help/digit | 28 +- help/environment | 5 +- help/fgetfield | 8 +- help/fgetstr | 7 +- help/files | 16 +- help/fputstr | 8 +- help/freeredc | 7 +- help/indices | 38 +- help/interrupt | 16 +- help/isptr | 20 +- help/issq | 13 +- help/mat | 151 +++--- help/newerror | 16 +- help/param | 16 +- help/prompt | 7 +- help/protect | 178 +++---- help/runtime | 8 +- help/sleep | 17 +- help/test | 20 +- help/variable | 95 +++- quickhash.c | 5 +- version.c | 6 +- zfunc.c | 161 +++++- zmath.h | 15 +- zmod.c | 6 +- 43 files changed, 2651 insertions(+), 829 deletions(-) create mode 100644 cal/alg_config.cal diff --git a/CHANGES b/CHANGES index 9cfa256..b13be92 100644 --- a/CHANGES +++ b/CHANGES @@ -38,8 +38,8 @@ The following are the changes from calc version 2.12.0 to date: etc.) for VT100 terminals and terminal window emulators (i.e., xterm, Apple OS/X Terminal, etc.) that support them. For example: - read screen - print green:"This is green. ":red:"This is red.":black + ; read screen + ; print green:"This is green. ":red:"This is red.":black Fixed a bug where too many open files returned E_FOPEN3. Now a new error symbol F_MANYOPEN is used for too many open files. @@ -134,14 +134,14 @@ The following are the changes from calc version 2.12.0 to date: Global variables and functions must be declared ahead of time because the dotest scope of evaluation is a line at a time. For example: - read dotest.cal - read set8700.cal - dotest("set8700.line"); + ; read dotest.cal + ; read set8700.cal + ; dotest("set8700.line"); Updated the todo / wish list items. The top priority now is to convert calc to GNU autoconf / configure to build the calc. - help todo + ; help todo Added missing help file for the stoponerror() builtin. @@ -179,6 +179,87 @@ The following are the changes from calc version 2.12.0 to date: no other compile errors, only the unterminated comment will stop completion of the function being defined. + Added the reading of more calc resource files to the cal/regress.cal + regression test. + + The issq() test had a slight performance boost. A minor note + was added to the help/issq file. + + Improved the documentation of the mul2, sq2, pow2, and redc2 config + parameters in help/config. + + Added config("baseb"), a read-only configuration value to return + the number of bits in the fundamental base in which calculations + are performed. This is a read-only configuration value. + + Calc now permits such as: + + ++*p-- ++*----*++p---- + + where p is an lvalue; successful evaluation of course require the + successive operations to be performed to have operands of appropriate + types; e.g. in *A, A is usually an lvalue whose current value is a + pointer. ++ and -- act on lvalues. In the above examples there are + implied parentheses from the beginning to immediately after p. If + there are no pre ++ or -- operations, as in + + **p++ + + the implied parentheses are from immediately before p to the end. + + Improved the error message when && is used as a prefix operator. + + Changed the help/config file to read like a builtin function + help file. + + One can no longer set to 1, or to a value < 0, the config() + parameters: "mul2", "sq2", "pow2", and "redc2". These values + in the past would result in improper configuration of internal + calc algorithms. Changed cal/test4100.cal to use the minimal + value of 2 for "pow2", and "redc2". + + Changed the default values for the following config() parameters: + + config("mul2") == 1780 + config("sq2") == 3388 + config("pow2") == 176 + + These values were determined established on a 1.8GHz AMD 32-bit + CPU of ~3406 BogoMIPS by the new resource file: + + cal/alg_config.cal + + Regarding the alg_config.cal resource file: + + The best_mul2() function returns the optimal value of config("mul2"). + The best_sq2() function returns the optimal value of config("sq2"). + The best_pow2() function returns the optimal value of config("pow2"). + The other functions are just support functions. + + By design, best_mul2(), best_sq2(), and best_pow2() take a few + minutes to run. These functions increase the number of times a + given computational loop is executed until a minimum amount of CPU + time is consumed. To watch these functions progress, one can set + the config("user_debug") value. + + Here is a suggested way to use the alg_config.cal resource file: + + ; read alg_config + ; config("user_debug",2),; + ; best_mul2(); best_sq2(); best_pow2(); + ; best_mul2(); best_sq2(); best_pow2(); + ; best_mul2(); best_sq2(); best_pow2(); + + NOTE: It is perfectly normal for the optimal value returned + to differ slightly from run to run. Slight variations due to + inaccuracy in CPU timings will cause the best value returned to + differ slightly from run to run. + + See "help resource" for more information on alg_config.cal. + + Updated the "help variable" text to reflect the current calc + use of ` (backquote), * (star), and & (ampersand). + The following are the changes from calc version 2.11.10.1 to 2.11.11: @@ -1094,11 +1175,11 @@ The following are the changes from calc version 2.11.3t0 to 2.11.4: files may be referred to in succession by separating their names by whitespace. For example: - > read alpha beta gamma; + ; read alpha beta gamma; does essentially the same as: - > read alpha; read beta; read gamma; + ; read alpha; read beta; read gamma; This is convenient for commands like: @@ -1123,7 +1204,7 @@ The following are the changes from calc version 2.11.3t0 to 2.11.4: multiple read statement, -once applies only to the next named file. For example - > read -once alpha beta -once gamma; + ; read -once alpha beta -once gamma; will read alpha and gamma only if they have not already been read, but in any case, will read beta. @@ -1131,7 +1212,7 @@ The following are the changes from calc version 2.11.3t0 to 2.11.4: (8) A fault in the programming for the cd command has been corrected so that specifying a directory by a string constant will work. E.g: - > cd "my work" + ; cd "my work" should work if the current directory has a directory with name "my work". @@ -1191,17 +1272,17 @@ The following are the changes from calc version 2.11.3t0 to 2.11.4: (16) "global" and "local" may now be used in expressions. For example: - > for (local i = 0; i < 5; i++) print i^2; + ; for (local i = 0; i < 5; i++) print i^2; is now acceptable, as is: - > define f(x = global x) = (global x = x)^2; + ; define f(x = global x) = (global x = x)^2; which breaks wise programming rules and would probably better be handled by something like: - > global x - > define f(t = x) = (x = t)^2; + ; global x + ; define f(t = x) = (x = t)^2; Both definitions produce the same code for f. For non-null t, f(t) returns t^2 and assigns the value of t to x; f() and f(t) with null t @@ -1219,11 +1300,11 @@ The following are the changes from calc version 2.11.3t0 to 2.11.4: either 32 or 64-bit longs. In setting such components, the arguments are now to less than 2^31. Before this change: - > config("mul2", 2^32 + 3) + ; config("mul2", 2^32 + 3) would be accepted on a 64-bit machine but result in the same as: - > config("mul2", 3) + ; config("mul2", 3) The following are the changes from calc version 2.11.2t0 to 2.11.2t1.0: @@ -1462,9 +1543,9 @@ The following are the changes from calc version 2.11.0t10 to 2.11.0t11: The power(a, b, epsilon) builtin will return a "too-large result" if an estimate indicates that the result will have absolute value - > 2^2^30 * epsilon. Otherwise the evaluation will be attempted - but may fail due to shortage of memory or may require a long - runtime if the result will be very large. + that is > 2^2^30 * epsilon. Otherwise the evaluation will be + attempted but may fail due to shortage of memory or may require + a long runtime if the result will be very large. Changes have been made to the algorithms used for some special functions sinh(), cosh(), tanh(), sin(), cos(), etc., that make @@ -2500,10 +2581,10 @@ The following are the changes from calc version 2.10.3t5.34 to 2.10.3t5.37: of links to the occurrence of that argument that is being referred to. For example, supposing "abc" has not been used earlier: - > A = "abc" - > links(A) + ; A = "abc" + ; links(A) 2 - > links(A) + ; links(A) 1 The two links in the first call are to A and the current "oldvalue"; @@ -2798,11 +2879,11 @@ The following are the changes from calc version 2.10.3t5.34 to 2.10.3t5.37: (30) Although it is not illegal, it seems pointless to use a comma operator with a constant or simple variable as in - > 2 * 3,14159 + ; 2 * 3,14159 14159 - > a = 4; b = 5; - > A = (a , b + 2); - > A + ; a = 4; b = 5; + ; A = (a , b + 2); + ; A 7 I have added a few lines to addop.c so that when this occurs a @@ -2833,27 +2914,27 @@ The following are the changes from calc version 2.10.3t5.34 to 2.10.3t5.37: Here is a demo: - > global a; - > - > define f(x) {local i = x^2; a++; - >> if (x > 5) quit "Too large!"; return i;} + ; global a; + ; + ; define f(x) {local i = x^2; a++; + ;; if (x > 5) quit "Too large!"; return i;} f() defined - > define g(x) = f(x) + f(2*x); + ; define g(x) = f(x) + f(2*x); g() defined - > g(2) + ; g(2) 20 - > g(3) + ; g(3) Too large! "f": line 3 "g": line 0 "*": line 6 - > eval("g(3)") + ; eval("g(3)") Too large! "f": line 3 "g": line 0 "**": line 1 "*": line 7 - > a + ; a 6 (32) I've made several small changes like removing @@ -2899,14 +2980,14 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: a variable as in p = &var, and then *p in expressions has the same effect as var. Here is a simple example of their use: - > define s(L) {local v=0; while (size(L)) v+= *pop(L);return v;} + ; define s(L) {local v=0; while (size(L)) v+= *pop(L);return v;} s() defined - > global a = 1, b = 2; - > L = list(&a, &b); - > print s(L) + ; global a = 1, b = 2; + ; L = list(&a, &b); + ; print s(L) 3 - > b = 3; - > print s(L) + ; b = 3; + ; print s(L) 4 Octet-pointers, number-pointers, and string-pointers in @@ -2918,11 +2999,11 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: Some arithmetic operations has been defined for corresponding C operations. For example: - > A = mat[4]; - > p = &A[0]; - > *(p+2) == A[2] - > ++p - > *p == A[1] + ; A = mat[4]; + ; p = &A[0]; + ; *(p+2) == A[2] + ; ++p + ; *p == A[1] There is at present no protection against "illegal" use of & and *, e.g. if one attempts here to assign a value to *(p+5), @@ -2935,28 +3016,28 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: X; in effect X is an address and *X is the value at X. Added isptr(p) builtin to return 0 is p is not a pointer, - >0 if it is a pointer. The value of isptr(p) comes from the - V_XYZ #define (see the top of value.h) of the value to which - p points. + and >0 if it is a pointer. The value of isptr(p) comes from + the V_XYZ #define (see the top of value.h) of the value to + which p points. To allow & to be used as a C-like address operator, use of it has been dropped in calls to user-defined functions. For the time being I have replaced it by the back-quote `. For example: - > global a - > define f(a,b) = a = b - > f(&a,5) - > print a + ; global a + ; define f(a,b) = a = b + ; f(&a,5) + ; print a 0 - > f(`a,5) - > print a + ; f(`a,5) + ; print a 5 However, one may use & in a similar way as in: - > define g(a,b) = *a = b - > g(&a, 7) - > print a + ; define g(a,b) = *a = b + ; g(&a, 7) + ; print a 7 There is no hashvalue for pointers. Thus, like error values, @@ -2964,38 +3045,38 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: The -> also works in calc. For example: - > obj xy {x,y} - > obj uvw {u, v, w} - > obj xy A = {1,2} - > obj uvw B = {3,4,5} - > p = &A - > q = &B - > p->x + ; obj xy {x,y} + ; obj uvw {u, v, w} + ; obj xy A = {1,2} + ; obj uvw B = {3,4,5} + ; p = &A + ; q = &B + ; p->x 1 - > p->y = 6 - > A + ; p->y = 6 + ; A obj xy {1, 6} - > q -> u + ; q -> u 3 - > p->y = q - > A + ; p->y = q + ; A obj xy {1, v-ptr: 1400474c0} - > p->y->u + ; p->y->u 3 - > p->y->u = 7 - > B + ; p->y->u = 7 + ; B obj uvw {7, 4, 5} - > p -> y = p - > A + ; p -> y = p + ; A obj xy {1, v-ptr: 140047490} - > p -> y -> x + ; p -> y -> x 1 - > p->y->y + ; p->y->y v-ptr: 140047490 - > p->y->y-> x + ; p->y->y-> x 1 - > p->y->y->x = 8 - > A + ; p->y->y->x = 8 + ; A obj xy {8, v-ptr: 140047490} @@ -3023,14 +3104,14 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: The prior method calc has used for handling "constants" amounted to leakage. After: - > define f(x) = 27 + x; - > a = 27; + ; define f(x) = 27 + x; + ; a = 27; It is of course necessary for the constant 27 to be stored, but if one now redefines f and a by: - > define f(x) = 45 + x; - > a = 45; + ; define f(x) = 45 + x; + ; a = 45; There seems little point in retaining 27 as a constant and therefore using up memory. If this example seems trivial, @@ -3112,16 +3193,16 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: The "." value: - > 2 + 2 + ; 2 + 2 4 - > . + ; . 4 can now be treated as an unnamed variable. For example: - > mat x[3,3]={1,2,3,4,5,6,7,8,9} - > x - > print .[1,2] + ; mat x[3,3]={1,2,3,4,5,6,7,8,9} + ; x + ; print .[1,2] 6 (9) for a list L defining L[i] to be same as L[[i]] @@ -3158,18 +3239,18 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: For example: - > A = list(1,2,4); - > B = mat[2,2] = {5,6,7,8}; - > define f(x) = (x ? A : B)[[1]]; - > print f(1), f(0) + ; A = list(1,2,4); + ; B = mat[2,2] = {5,6,7,8}; + ; define f(x) = (x ? A : B)[[1]]; + ; print f(1), f(0) 2 6 - > obj xy {x,y} - > C = obj xy = {4,5} - > p = &C - > *p.x + ; obj xy {x,y} + ; C = obj xy = {4,5} + ; p = &C + ; *p.x Not indexing matrix or object - > (*p).x + ; (*p).x 4 (14) swap(a,b) now permits swapping of octets in the same or different @@ -3177,10 +3258,10 @@ The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33: For example: - > A = blk() = {1,2,3} - > B = blk() = {4,5,6} - > swap(A[0], B[2]) - > A + ; A = blk() = {1,2,3} + ; B = blk() = {4,5,6} + ; swap(A[0], B[2]) + ; A chunksize = 256, maxsize = 256, datalen = 3 060203 @@ -3316,12 +3397,12 @@ The following are the changes from calc version 2.10.3t5.11 to 2.10.3t5.27: Blocks will expand when required by the copy() builtin function: - > f = fopen("help/full", "r") - > B = blk() - > B + ; f = fopen("help/full", "r") + ; B = blk() + ; B chunksize = 256, maxsize = 256, datalen = 0 - > copy(B, f) - > B + ; copy(B, f) + ; B chunksize = 256, maxsize = 310272, datalen = 310084 2a2a2a2a2a2a2a2a2a2a2a2a2a0a2a20696e74726f0a2a2a2a2a2a2a2a2a... @@ -4241,11 +4322,11 @@ The following are the changes from calc version 2.10.2t25 to 2.10.2t32: "global a" is read in the last line. Thus one may now use the same name in several "static" areas as in: - > static a = 10; - > define f(x) = a + x; - > static a = 20; - > define g(x) = a + x; - > global a; + ; static a = 10; + ; define f(x) = a + x; + ; static a = 20; + ; define g(x) = a + x; + ; global a; The first "a" exists only for the definition of f(); the second "a" only for the definition of g(). At the end one has only @@ -4254,10 +4335,10 @@ The following are the changes from calc version 2.10.2t25 to 2.10.2t32: Ending the scope of a static variable in this way is consistent with the normal use of static variables as in: - > static a = 10; - > define f(x) {static a = 20; return a++ + x;} - > define g(x) = a + x; - > global a; + ; static a = 10; + ; define f(x) {static a = 20; return a++ + x;} + ; define g(x) = a + x; + ; global a; The scope of the first "a" is temporarily interrupted by the "static a" in the second line; the second "a" remains active @@ -4273,12 +4354,12 @@ The following are the changes from calc version 2.10.2t25 to 2.10.2t32: to me that its use must end the scope of any static "a". Thus the changes I introduce are such that after: - > global a = 10; - > define f(x) = a + x; - > static a = 20; - > define g(x) = a + x; - > define h(x) {global a = 30; return a + x;} - > define i(x) = a + x; + ; global a = 10; + ; define f(x) = a + x; + ; static a = 20; + ; define g(x) = a + x; + ; define h(x) {global a = 30; return a + x;} + ; define i(x) = a + x; g(x) will always return 20 + x, and until h(x) has been called, f(x) and i(x) will return 10 + x; when h(x) is called, it @@ -4425,8 +4506,8 @@ The following are the changes from calc version 2.10.2t4 to 2.10.2t24: The show keyword is now a statement instead of a command: - > define demo() {local f = open("foo", "w"); show files; fclose(f);} - > demo() + ; define demo() {local f = open("foo", "w"); show files; fclose(f);} + ; demo() Added a new trace option for display of links to real and complex numbers. This is activated by config("trace", 4). The printing of @@ -4905,13 +4986,13 @@ The following are the changes from calc version 2.10.1t21 to 2.10.2t0: The param(n) builtin, then n > 0, may be used as an lvalue: - > define g() = (param(2) = param(1)); - > define h() = (param(1)++, param(2)--); - > u = 5 - > v = 10 - > print g(u, &v), u, v; + ; define g() = (param(2) = param(1)); + ; define h() = (param(1)++, param(2)--); + ; u = 5 + ; v = 10 + ; print g(u, &v), u, v; 5 5 5 - > print h(&u, &v), u, v; + ; print h(&u, &v), u, v; 5 6 4 Missing args now evaluate to null as in: @@ -5272,9 +5353,9 @@ The following are the changes from calc version 2.10.0t13 to 2.10.1t10: C-style arbitrary precision calculator (version 2.10.1t3) [Type "exit" to exit, or "help" for help.] - > files(5) + ; files(5) FILE 5 "descriptor[5]" (unknown_mode, pos 0) - > fgetline(files(5)) + ; fgetline(files(5)) "A line of text in the file on descriptor 5" The -m mode flag now controls calc's ability to open files @@ -5996,8 +6077,8 @@ Following is a list of visible changes to calc from version 1.24.7 to 1.26.1: ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.78 $ -## @(#) $Id: CHANGES,v 29.78 2006/06/03 22:52:39 chongo Exp $ +## @(#) $Revision: 29.80 $ +## @(#) $Id: CHANGES,v 29.80 2006/06/11 07:52:58 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/RCS/CHANGES,v $ ## ## Under source code control: 1993/06/02 18:12:57 diff --git a/cal/Makefile b/cal/Makefile index 5ee6068..d40d526 100644 --- a/cal/Makefile +++ b/cal/Makefile @@ -18,8 +18,8 @@ # received a copy with calc; if not, write to Free Software Foundation, Inc. # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # -# @(#) $Revision: 29.18 $ -# @(#) $Id: Makefile,v 29.18 2006/05/20 19:32:40 chongo Exp $ +# @(#) $Revision: 29.19 $ +# @(#) $Id: Makefile,v 29.19 2006/06/10 13:01:34 chongo Exp $ # @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/Makefile,v $ # # Under source code control: 1991/07/21 05:00:54 @@ -177,7 +177,7 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \ beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \ randomrun.cal repeat.cal xx_print.cal natnumset.cal qtime.cal \ test8400.cal test8500.cal test8600.cal chi.cal intfile.cal screen.cal \ - dotest.cal set8700.cal set8700.line + dotest.cal set8700.cal set8700.line alg_config.cal # These files are found (but not built) in the distribution # diff --git a/cal/README b/cal/README index c1ecaa6..a3d0120 100644 --- a/cal/README +++ b/cal/README @@ -75,7 +75,7 @@ have meanings are as follows: is displayed. 2 Show func will display more information about a functions - arguments as well as more argument sdummary information. + arguments as well as more argument summary information. 3 During execution, allow calc standard resource files to output additional debugging information. @@ -103,7 +103,7 @@ either of the bottom 2 bits set: print "funcB(size, mass, ...) defined"; } -If your the resource file needs to output special debugging informatin, +If your the resource file needs to output special debugging information, we recommend that you check for bit 3 of the config("resource_debug") before printing the debug statement: @@ -117,12 +117,68 @@ The following is a brief description of some of the calc resource files that are shipped with calc. See above for example of how to read in and execute these files. +alg_config.cal + + global test_time + mul_loop(repeat,x) defined + mul_ratio(len) defined + best_mul2() defined + sq_loop(repeat,x) defined + sq_ratio(len) defined + best_sq2() defined + pow_loop(repeat,x,ex) defined + pow_ratio(len) defined + best_pow2() defined + + These functions search for an optimal value of config("mul2"), + config("sq2"), and config("pow2"). The calc default values of these + configuration values were set by running this resource file on a + 1.8GHz AMD 32-bit CPU of ~3406 BogoMIPS. + + The best_mul2() function returns the optimal value of config("mul2"). + The best_sq2() function returns the optimal value of config("sq2"). + The best_pow2() function returns the optimal value of config("pow2"). + The other functions are just support functions. + + By design, best_mul2(), best_sq2(), and best_pow2() take a few + minutes to run. These functions increase the number of times a + given computational loop is executed until a minimum amount of CPU + time is consumed. To watch these functions progress, one can set + the config("user_debug") value. + + Here is a suggested way to use this resource file: + + ; read alg_config + ; config("user_debug",2),; + ; best_mul2(); best_sq2(); best_pow2(); + ; best_mul2(); best_sq2(); best_pow2(); + ; best_mul2(); best_sq2(); best_pow2(); + + NOTE: It is perfectly normal for the optimal value returned to differ + slightly from run to run. Slight variations due to inaccuracy in + CPU timings will cause the best value returned to differ slightly + from run to run. + + One can use a calc startup file to change the initial values of + config("mul2"), config("sq2"), and config("pow2"). For example one + can place into ~/.calcrc these lines: + + config("mul2", 1780),; + config("sq2", 3388),; + config("pow2", 176),; + + to automatically and silently change these config values. + See help/config and CALCRC in help/environment for more information. + + beer.cal Calc's contribution to the 99 Bottles of Beer web page: http://www.ionet.net/~timtroyr/funhouse/beer.html#calc + NOTE: This resource produces a lot of output. :-) + bernoulli.cal @@ -132,7 +188,7 @@ bernoulli.cal NOTE: There is now a bernoulli() builtin function. This file is left here for backward compatibility and now simply returns - the buildin function. + the builtin function. bigprime.cal @@ -153,9 +209,9 @@ chi.cal The chi_prob() function does not work well with odd degrees of freedom. It is reasonable with even degrees of freedom, although one must give - a sifficently small error term as the degress gets large (>100). + a sufficiently small error term as the degrees gets large (>100). - The Z(x) and P(x) are internal statistical funcions. + The Z(x) and P(x) are internal statistical functions. eps is an optional epsilon() like error term. @@ -226,6 +282,8 @@ hello.cal http://www.latech.edu/~acm/HelloWorld.shtml http://www.latech.edu/~acm/helloworld/calc.html + NOTE: This resource produces a lot of output. :-) + intfile.cal @@ -935,8 +993,8 @@ xx_print.cal ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.12 $ -## @(#) $Id: README,v 29.12 2006/05/21 04:41:09 chongo Exp $ +## @(#) $Revision: 29.14 $ +## @(#) $Id: README,v 29.14 2006/06/11 07:22:05 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/README,v $ ## ## Under source code control: 1990/02/15 01:50:32 diff --git a/cal/alg_config.cal b/cal/alg_config.cal new file mode 100644 index 0000000..3a67c9f --- /dev/null +++ b/cal/alg_config.cal @@ -0,0 +1,1253 @@ +/* + * alg_config - help determine optimal values for algorithm levels + * + * Copyright (C) 2006 Landon Curt Noll + * + * 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. + * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * @(#) $Revision: 29.14 $ + * @(#) $Id: alg_config.cal,v 29.14 2006/06/11 07:22:05 chongo Exp $ + * @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/alg_config.cal,v $ + * + * Under source code control: 2006/06/07 14:10:11 + * File existed as early as: 2006 + * + * chongo /\oo/\ http://www.isthe.com/chongo/ + * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ + */ + + +global test_time; /* try for this many seconds in loop test */ + + +/* + * mul_loop - measure the CPU time to perform a set of multiply loops + * + * given: + * repeat number of multiply loops to perform + * x array of 5 values, each the same length in BASEB-bit words + * + * NOTE: When their lengths are 1 BASEB-bit word, then a + * dummy loop of simple constants are used. Thus the + * length == 1 is an approximation of loop overhead. + * + * returns: + * approximate runtime to perform repeat the multiply loops + * + * NOTE: This is an internal support function that is normally + * not called directly from the command line. Call the + * function best_mul2() instead. + */ +define mul_loop(repeat, x) +{ + local start; /* start of execution */ + local end; /* end of execution */ + local answer; /* multiplicand */ + local len; /* length of each element */ + local baseb_bytes; /* bytes in a BASEB-bit word */ + local i; + + /* firewall */ + if (!isint(repeat) || repeat < 0) { + quit "mul_loop: 1st arg: repeat must be an integer > 0"; + } + if (size(*x) != 5) { + quit "mul_loop: 2nd arg matrix does not have 5 elements"; + } + if (matdim(*x) != 1) { + quit "mul_loop: 2nd arg matrix is not 1 dimensional"; + } + if (matmin(*x, 1) != 0) { + quit "mul_loop: 2nd arg matrix index range does not start with 0"; + } + if (matmax(*x, 1) != 4) { + quit "mul_loop: 2nd arg matrix index range does not end with 4"; + } + + baseb_bytes = config("baseb") / 8; + len = sizeof((*x)[0]) / baseb_bytes; + for (i=1; i < 4; ++i) { + if ((sizeof((*x)[i]) / baseb_bytes) != len) { + quit "mul_loop: 2nd arg matrix elements are not of equal BASEB-bit word length"; + } + } + + /* multiply pairwise, all sets of a given length */ + start = runtime(); + for (i=0; i < repeat; ++i) { + + if (len == 1) { + /* we use len == 1 to test this tester loop overhead */ + answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; + /**/ + answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; + /**/ + answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; + /**/ + answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; + /**/ + answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; answer = 0 * 0; + } else { + answer = (*x)[0] * (*x)[1]; + answer = (*x)[0] * (*x)[2]; + answer = (*x)[0] * (*x)[3]; + answer = (*x)[0] * (*x)[4]; + /**/ + answer = (*x)[1] * (*x)[0]; + answer = (*x)[1] * (*x)[2]; + answer = (*x)[1] * (*x)[3]; + answer = (*x)[1] * (*x)[4]; + /**/ + answer = (*x)[2] * (*x)[0]; + answer = (*x)[2] * (*x)[1]; + answer = (*x)[2] * (*x)[3]; + answer = (*x)[2] * (*x)[4]; + /**/ + answer = (*x)[3] * (*x)[0]; + answer = (*x)[3] * (*x)[1]; + answer = (*x)[3] * (*x)[2]; + answer = (*x)[3] * (*x)[4]; + /**/ + answer = (*x)[4] * (*x)[0]; + answer = (*x)[4] * (*x)[1]; + answer = (*x)[4] * (*x)[2]; + answer = (*x)[4] * (*x)[3]; + } + } + + /* + * return duration + */ + end = runtime(); + return end-start; +} + + +/* + * mul_ratio - ratio of rates of 1st and 2nd multiply algorithms + * + * given: + * len length in BASEB-bit words to multiply + * + * return: + * ratio of (1st / 2nd) algorithm rate + * + * When want to determine a rate to a precision of 1 part in 1000. + * Most systems today return CPU time to at least 10 msec precision. + * So to get rates to that precision, we need to time loops to at + * least 1000 times as long as the precision (10 msec * 1000) + * which usually requires timing of loops that last 10 seconds or more. + * + * NOTE: This is an internal support function that is normally + * not called directly from the command line. Call the + * function best_mul2() instead. + */ +define mul_ratio(len) +{ + local mat x[5]; /* array of values for mul_loop to multiply */ + local mat one[5]; /* array if single BASEB-bit values */ + local baseb; /* calc word size in bits */ + local orig_cfg; /* caller configuration */ + local loops; /* number of multiply loops to time */ + local tlen; /* time to perform some number of loops */ + local tover; /* est of time for loop overhead */ + local alg1_rate; /* loop rate of 1st algorithm */ + local alg2_rate; /* loop rate of 2nd algorithm */ + local i; + + /* + * firewall + */ + if (!isint(len) || len < 2) { + quit "mul_ratio: 1st arg: len is not an integer > 1"; + } + + /* + * remember the caller's config state + */ + orig_cfg = config("all"); + config("mul2", 0),; + config("sq2", 0),; + config("pow2", 0),; + config("redc2", 0),; + config("tilde", 0),; + + /* + * initialize x, the values we will multiply + * + * We want these tests to be repeatable as possible, so we will seed + * the PRNG in a deterministic way. + */ + baseb = config("baseb"); + srand(sha1(sha1(baseb, config("version")))); + for (i=0; i < 5; ++i) { + /* force the values to be a full len words long */ + x[i] = ((1<<(((len-1) * baseb) + baseb-1)) | + randbit(((len-1) * baseb) + baseb-2)); + /* single BASEB-bit values */ + one[i] = 1; + } + + /* + * determine the number of loops needed to test 1st alg + */ + config("mul2", 2^31-1),; + loops = 1/2; + do { + loops *= 2; + tlen = mul_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg1 loops %d took %.3f sec\n", loops, tlen); + } + } while (tlen < 1.0); + + /* + * determine the 1st algorithm rate + */ + loops = max(1, ceil(loops * test_time / tlen)); + if (loops < 8) { + if (config("user_debug") > 1) { + printf(" we must expand loop test time to more than %d secs\n", + ceil(test_time * (8 / loops))); + } + loops = 8; + } + if (config("user_debug") > 3) { + printf("\t will try alg1 %d loops\n", loops); + } + tlen = mul_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg1 time = %.3f secs\n", tlen); + } + tover = mul_loop(loops, &one); + if (config("user_debug") > 3) { + printf("\t alg1 overhead look %.3f secs\n", tover); + } + if (tlen <= tover) { + quit "mul_ratio: overhead >= loop time"; + } + alg1_rate = loops / (tlen - tover); + if (config("user_debug") > 2) { + printf("\tmultiply alg1 rate = %.3f loopsets/sec\n", alg1_rate); + } + if (alg1_rate <= 0.0) { + quit "mul_ratio: alg1 rate was <= 0.0"; + } + + /* + * determine the number of loops needed to test 1st alg + */ + config("mul2", 2),; + loops = 1/2; + do { + loops *= 2; + tlen = mul_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg2 loops %d took %.3f sec\n", loops, tlen); + } + } while (tlen < 1.0); + + /* + * determine the 2nd algorithm rate + */ + loops = max(1, ceil(loops * test_time / tlen)); + if (loops < 8) { + if (config("user_debug") > 1) { + printf(" we must expand loop test time to more than %d secs\n", + ceil(test_time * (8 / loops))); + } + loops = 8; + } + tlen = mul_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg2 time = %.3f secs\n", tlen); + } + tover = mul_loop(loops, &one); + if (config("user_debug") > 3) { + printf("\t alg2 overhead look %.3f secs\n", tover); + } + if (tlen <= tover) { + quit "mul_ratio: overhead >= loop time"; + } + alg2_rate = loops / (tlen - tover); + if (config("user_debug") > 2) { + printf("\tmultiply alg2 rate = %.3f loopsets/sec\n", alg2_rate); + } + if (alg2_rate <= 0.0) { + quit "mul_ratio: alg2 rate was <= 0.0"; + } + + /* + * restore old config + */ + config("all", orig_cfg),; + + /* + * return alg1 / alg2 rate ratio + */ + return (alg1_rate / alg2_rate); +} + + +/* + * best_mul2 - determine the best config("mul2") parameter + * + * NOTE: Due to precision problems with CPU measurements, it is not + * unusual for the output of this function to vary slightly + * from run to run. + * + * NOTE: This function is designed to take a long time to run. + * We recommend setting: + * + * config("user_debug", 2) + * + * so that yon can watch the progress of this function. + */ +define best_mul2() +{ + local ratio; /* previously calculated alg1/alg2 ratio */ + local low; /* low loop value tested */ + local high; /* low loop value tested */ + local expand; /* how fast to expand the length */ + + /* + * setup + */ + test_time = 15.0; + if (config("user_debug") > 0) { + printf("will start with loop test time of %d secs\n", test_time); + } + + /* + * firewall - must have a >1 ratio for the initial length + */ + high = 16; + if (config("user_debug") > 0) { + printf("testing multiply alg1/alg2 ratio for len = %d\n", high); + } + ratio = mul_ratio(high); + if (config("user_debug") > 1) { + printf(" multiply alg1/alg2 ratio = %.3f\n", ratio); + } + if (ratio <= 1.0) { + quit "best_mul2: tests imply config(\"mul2\") should be < 4"; + } + + /* + * expand lengths until the ratio flips + */ + do { + /* + * determine the paramters of the next ratio test + * + * We will multiplicatively expand our test level until + * the ratio drops below 1.0. + */ + expand = ((ratio >= 3.5) ? 16 : 2^round(ratio)); + low = high; + high *= expand; + if (config("user_debug") > 1) { + printf(" expand the next test range by a factor of %d\n", + expand); + } + + /* + * determine the alg1/alg2 test ratio for this new length + */ + if (high >= 2^31) { + quit "best_mul2: tests imply config(\"mul2\") should be >= 2^31"; + } + if (config("user_debug") > 0) { + printf("testing multiply alg1/alg2 ratio for len = %d\n", high); + } + ratio = mul_ratio(high); + if (config("user_debug") > 1) { + printf(" multiply alg1/alg2 ratio = %.3f\n", ratio); + } + } while (ratio >= 1.0); + if (config("user_debug") > 0) { + printf("alg1/alg2 ratio now < 1.0, starting binary search between %d and %d\n", + low, high); + } + + /* + * binary search between low and high, for where ratio is just under 1.0 + */ + while (low+1 < high) { + + /* try the mid-point */ + if (config("user_debug") > 0) { + printf("testing multiply alg1/alg2 ratio for len = %d\n", + int((low+high)/2)); + } + ratio = mul_ratio(int((low+high)/2)); + if (config("user_debug") > 1) { + printf(" multiply alg1/alg2 ratio = %.3f\n", ratio); + } + + /* bump lower range up if we went over */ + if (ratio >= 1.0) { + if (config("user_debug") > 2) { + printf("\tmove low from %d up to %d\n", + low, int((low+high)/2)); + } + low = int((low+high)/2); + + /* drop higher range down if we went under */ + } else { + if (config("user_debug") > 2) { + printf("\tmove high from %d down to %d\n", + high, int((low+high)/2)); + } + high = int((low+high)/2); + } + } + + /* + * return on the suggested config("mul2") value + */ + if (config("user_debug") > 0) { + printf("best value of config(\"mul2\") is %d\n", + (ratio >= 1.0) ? high : low); + } + return ((ratio >= 1.0) ? high : low); +} + + +/* + * sq_loop - measure the CPU time to perform a set of square loops + * + * given: + * repeat number of square loops to perform + * x array of 5 values, each the same length in BASEB-bit words + * + * NOTE: When their lengths are 1 BASEB-bit word, then a + * dummy loop of simple constants are used. Thus the + * length == 1 is an approximation of loop overhead. + * returns: + * approximate runtime to perform a square loop + * + * NOTE: This is an internal support function that is normally + * not called directly from the command line. Call the + * function best_sq2() instead. + */ +define sq_loop(repeat, x) +{ + local start; /* start of execution */ + local end; /* end of execution */ + local answer; /* squared value */ + local len; /* length of each element */ + local baseb_bytes; /* bytes in a BASEB-bit word */ + local i; + + /* firewall */ + if (!isint(repeat) || repeat < 0) { + quit "sq_loop: 1st arg: repeat must be an integer > 0"; + } + if (size(*x) != 5) { + quit "sq_loop: 2nd arg matrix does not have 5 elements"; + } + if (matdim(*x) != 1) { + quit "sq_loop: 2nd arg matrix is not 1 dimensional"; + } + if (matmin(*x, 1) != 0) { + quit "sq_loop: 2nd arg matrix index range does not start with 0"; + } + if (matmax(*x, 1) != 4) { + quit "sq_loop: 2nd arg matrix index range does not end with 4"; + } + baseb_bytes = config("baseb") / 8; + len = sizeof((*x)[0]) / baseb_bytes; + for (i=1; i < 4; ++i) { + if ((sizeof((*x)[i]) / baseb_bytes) != len) { + quit "sq_loop: 2nd arg matrix elements are not of equal BASEB-bit word length"; + } + } + + /* square pairwise, all sets of a given length */ + start = runtime(); + for (i=0; i < repeat; ++i) { + + if (len == 1) { + /* we use len == 1 to test this tester loop overhead */ + answer = 0^2; answer = 0^2; answer = 0^2; answer = 0^2; + answer = 0^2; + /**/ + answer = 0^2; answer = 0^2; answer = 0^2; answer = 0^2; + answer = 0^2; + /**/ + answer = 0^2; answer = 0^2; answer = 0^2; answer = 0^2; + answer = 0^2; + /**/ + answer = 0^2; answer = 0^2; answer = 0^2; answer = 0^2; + answer = 0^2; + } else { + /* one square loop */ + answer = (*x)[0]^2; + answer = (*x)[1]^2; + answer = (*x)[2]^2; + answer = (*x)[3]^2; + answer = (*x)[4]^2; + /**/ + answer = (*x)[0]^2; + answer = (*x)[1]^2; + answer = (*x)[2]^2; + answer = (*x)[3]^2; + answer = (*x)[4]^2; + /**/ + answer = (*x)[0]^2; + answer = (*x)[1]^2; + answer = (*x)[2]^2; + answer = (*x)[3]^2; + answer = (*x)[4]^2; + /**/ + answer = (*x)[0]^2; + answer = (*x)[1]^2; + answer = (*x)[2]^2; + answer = (*x)[3]^2; + answer = (*x)[4]^2; + } + } + + /* + * return duration + */ + end = runtime(); + return end-start; +} + + +/* + * sq_ratio - ratio of rates of 1st and 2nd square algorithms + * + * given: + * len length in BASEB-bit words to square + * + * return: + * ratio of (1st / 2nd) algorithm rates + * + * When want to determine a rate to a precision of 1 part in 1000. + * Most systems today return CPU time to at least 10 msec precision. + * So to get rates to that precision, we need to time loops to at + * least 1000 times as long as the precision (10 msec * 1000) + * which usually requires timing of loops that last 10 seconds or more. + * + * NOTE: This is an internal support function that is normally + * not called directly from the command line. Call the + * function best_sq2() instead. + */ +define sq_ratio(len) +{ + local mat x[5]; /* array of values for sq_loop to square */ + local mat one[5]; /* array if single BASEB-bit values */ + local baseb; /* calc word size in bits */ + local orig_cfg; /* caller configuration */ + local loops; /* number of square loops to time */ + local tlen; /* time to perform some number of loops */ + local tover; /* est of time for loop overhead */ + local alg1_rate; /* loop rate of 1st algorithm */ + local alg2_rate; /* loop rate of 2nd algorithm */ + local i; + + /* + * firewall + */ + if (!isint(len) || len < 2) { + quit "sq_ratio: 1st arg: len is not an integer > 1"; + } + + /* + * remember the caller's config state + */ + orig_cfg = config("all"); + config("mul2", 0),; + config("sq2", 0),; + config("pow2", 0),; + config("redc2", 0),; + config("tilde", 0),; + + /* + * initialize x, the values we will square + * + * We want these tests to be repeatable as possible, so we will seed + * the PRNG in a deterministic way. + */ + baseb = config("baseb"); + srand(sha1(sha1(baseb, config("version")))); + for (i=0; i < 5; ++i) { + /* force the values to be a full len words long */ + x[i] = ((1<<(((len-1) * baseb) + baseb-1)) | + randbit(((len-1) * baseb) + baseb-2)); + /* single BASEB-bit values */ + one[i] = 1; + } + + /* + * determine the number of loops needed to test 1st alg + */ + config("sq2", 2^31-1),; + loops = 1/2; + do { + loops *= 2; + tlen = sq_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg1 loops %d took %.3f sec\n", loops, tlen); + } + } while (tlen < 1.0); + + /* + * determine the 1st algorithm rate + */ + loops = max(1, ceil(loops * test_time / tlen)); + if (loops < 8) { + if (config("user_debug") > 1) { + printf(" we must expand loop test time to more than %d secs\n", + ceil(test_time * (8 / loops))); + } + loops = 8; + } + tlen = sq_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg1 time = %.3f secs\n", tlen); + } + tover = sq_loop(loops, &one); + if (config("user_debug") > 3) { + printf("\t alg1 overhead look %.3f secs\n", tover); + } + if (tlen <= tover) { + quit "sq_ratio: overhead >= loop time"; + } + alg1_rate = loops / (tlen - tover); + if (config("user_debug") > 2) { + printf("\tsquare alg1 rate = %.3f loopsets/sec\n", alg1_rate); + } + if (alg1_rate <= 0.0) { + quit "sq_ratio: alg1 rate was <= 0.0"; + } + + /* + * determine the number of loops needed to test 1st alg + */ + config("sq2", 2),; + loops = 1/2; + do { + loops *= 2; + tlen = sq_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg2 loops %d took %.3f sec\n", loops, tlen); + } + } while (tlen < 1.0); + + /* + * determine the 2nd algorithm rate + */ + loops = max(1, ceil(loops * test_time / tlen)); + if (loops < 8) { + if (config("user_debug") > 1) { + printf(" we must expand loop test time to more than %d secs\n", + ceil(test_time * (8 / loops))); + } + loops = 8; + } + tlen = sq_loop(loops, &x); + if (config("user_debug") > 3) { + printf("\t alg2 time = %.3f secs\n", tlen); + } + tover = sq_loop(loops, &one); + if (config("user_debug") > 3) { + printf("\t alg2 overhead look %.3f secs\n", tover); + } + if (tlen <= tover) { + quit "sq_ratio: overhead >= loop time"; + } + alg2_rate = loops / (tlen - tover); + if (config("user_debug") > 2) { + printf("\tsquare alg2 rate = %.3f loopsets/sec\n", alg2_rate); + } + if (alg2_rate <= 0.0) { + quit "sq_ratio: alg2 rate was <= 0.0"; + } + + /* + * restore old config + */ + config("all", orig_cfg),; + + /* + * return alg1 / alg2 rate ratio + */ + return (alg1_rate / alg2_rate); +} + + +/* + * best_sq2 - determine the best config("sq2") parameter + * + * NOTE: Due to precision problems with CPU measurements, it is not + * unusual for the output of this function to vary slightly + * from run to run. + * + * NOTE: This function is designed to take a long time to run. + * We recommend setting: + * + * config("user_debug", 2) + * + * so that yon can watch the progress of this function. + */ +define best_sq2() +{ + local ratio; /* previously calculated alg1/alg2 ratio */ + local low; /* low loop value tested */ + local high; /* low loop value tested */ + local expand; /* how fast to expand the length */ + + /* + * setup + */ + test_time = 15.0; + if (config("user_debug") > 0) { + printf("will start with loop test time of %d secs\n", test_time); + } + + /* + * firewall - must have a >1 ratio for the initial length + */ + high = 16; + if (config("user_debug") > 0) { + printf("testing square alg1/alg2 ratio for len = %d\n", high); + } + ratio = sq_ratio(high); + if (config("user_debug") > 1) { + printf(" square alg1/alg2 ratio = %.3f\n", ratio); + } + if (ratio <= 1.0) { + quit "best_sq2: tests imply config(\"sq2\") should be < 4"; + } + + /* + * expand lengths until the ratio flips + */ + do { + /* + * determine the paramters of the next ratio test + * + * We will multiplicatively expand our test level until + * the ratio drops below 1.0. + */ + expand = ((ratio >= 3.5) ? 16 : 2^round(ratio)); + low = high; + high *= expand; + if (config("user_debug") > 1) { + printf(" expand the next test range by a factor of %d\n", + expand); + } + + /* + * determine the alg1/alg2 test ratio for this new length + */ + if (high >= 2^31) { + quit "best_sq2: tests imply config(\"sq2\") should be >= 2^31"; + } + if (config("user_debug") > 0) { + printf("testing square alg1/alg2 ratio for len = %d\n", high); + } + ratio = sq_ratio(high); + if (config("user_debug") > 1) { + printf(" square alg1/alg2 ratio = %.3f\n", ratio); + } + } while (ratio >= 1.0); + if (config("user_debug") > 0) { + printf("alg1/alg2 ratio now < 1.0, starting binary search between %d and %d\n", + low, high); + } + + /* + * binary search between low and high, for where ratio is just under 1.0 + */ + while (low+1 < high) { + + /* try the mid-point */ + if (config("user_debug") > 0) { + printf("testing square alg1/alg2 ratio for len = %d\n", + int((low+high)/2)); + } + ratio = sq_ratio(int((low+high)/2)); + if (config("user_debug") > 1) { + printf(" square alg1/alg2 ratio = %.3f\n", ratio); + } + + /* bump lower range up if we went over */ + if (ratio >= 1.0) { + if (config("user_debug") > 2) { + printf("\tmove low from %d up to %d\n", + low, int((low+high)/2)); + } + low = int((low+high)/2); + + /* drop higher range down if we went under */ + } else { + if (config("user_debug") > 2) { + printf("\tmove high from %d down to %d\n", + high, int((low+high)/2)); + } + high = int((low+high)/2); + } + } + + /* + * return on the suggested config("sq2") value + */ + if (config("user_debug") > 0) { + printf("best value of config(\"sq2\") is %d\n", + (ratio >= 1.0) ? high : low); + } + return ((ratio >= 1.0) ? high : low); +} + + +/* + * pow_loop - measure the CPU time to perform a set of pmod loops + * + * given: + * repeat number of pmod loops to perform + * x array of 5 values, each the same length in BASEB-bit words + * + * NOTE: When their lengths are 1 BASEB-bit word, then a + * dummy loop of simple constants are used. Thus the + * length == 1 is an approximation of loop overhead. + * + * ex exponent for pmod value + * + * returns: + * approximate runtime to perform a pmod loop + * + * NOTE: This is an internal support function that is normally + * not called directly from the command line. Call the + * function best_pow2() instead. + */ +define pow_loop(repeat, x, ex) +{ + local start; /* start of execution */ + local end; /* end of execution */ + local answer; /* pmod value */ + local len; /* length of each element */ + local baseb_bytes; /* bytes in a BASEB-bit word */ + local i; + + /* firewall */ + if (!isint(repeat) || repeat < 0) { + quit "pow_loop: 1st arg: repeat must be an integer > 0"; + } + if (size(*x) != 5) { + quit "pow_loop: 2nd arg matrix does not have 5 elements"; + } + if (matdim(*x) != 1) { + quit "pow_loop: 2nd arg matrix is not 1 dimensional"; + } + if (matmin(*x, 1) != 0) { + quit "pow_loop: 2nd arg matrix index range does not start with 0"; + } + if (matmax(*x, 1) != 4) { + quit "pow_loop: 2nd arg matrix index range does not end with 4"; + } + baseb_bytes = config("baseb") / 8; + len = sizeof((*x)[0]) / baseb_bytes; + for (i=1; i < 4; ++i) { + if ((sizeof((*x)[i]) / baseb_bytes) != len) { + quit "pow_loop: 2nd arg matrix elements are not of equal BASEB-bit word length"; + } + } + if (!isint(ex) || ex < 3) { + quit" pow_loop: 3rd arg ex is not an integer > 2"; + } + + /* pmod pairwise, all sets of a given length */ + start = runtime(); + for (i=0; i < repeat; ++i) { + + if (len == 1) { + /* we use len == 1 to test this tester loop overhead */ + answer = pmod(0,0,0); answer = pmod(0,0,0); + answer = pmod(0,0,0); answer = pmod(0,0,0); + /**/ + answer = pmod(0,0,0); answer = pmod(0,0,0); + answer = pmod(0,0,0); answer = pmod(0,0,0); + /**/ + answer = pmod(0,0,0); answer = pmod(0,0,0); + answer = pmod(0,0,0); answer = pmod(0,0,0); + /**/ + answer = pmod(0,0,0); answer = pmod(0,0,0); + answer = pmod(0,0,0); answer = pmod(0,0,0); + /**/ + answer = pmod(0,0,0); answer = pmod(0,0,0); + answer = pmod(0,0,0); answer = pmod(0,0,0); + /**/ + answer = pmod(0,0,0); answer = pmod(0,0,0); + answer = pmod(0,0,0); answer = pmod(0,0,0); + } else { + answer = pmod((*x)[0], ex, (*x)[1]); + answer = pmod((*x)[0], ex, (*x)[2]); + answer = pmod((*x)[0], ex, (*x)[3]); + answer = pmod((*x)[0], ex, (*x)[4]); + /**/ + answer = pmod((*x)[1], ex, (*x)[0]); + answer = pmod((*x)[1], ex, (*x)[2]); + answer = pmod((*x)[1], ex, (*x)[3]); + answer = pmod((*x)[1], ex, (*x)[4]); + /**/ + answer = pmod((*x)[2], ex, (*x)[0]); + answer = pmod((*x)[2], ex, (*x)[1]); + answer = pmod((*x)[2], ex, (*x)[3]); + answer = pmod((*x)[2], ex, (*x)[4]); + /**/ + answer = pmod((*x)[3], ex, (*x)[0]); + answer = pmod((*x)[3], ex, (*x)[1]); + answer = pmod((*x)[3], ex, (*x)[2]); + answer = pmod((*x)[3], ex, (*x)[4]); + /**/ + answer = pmod((*x)[4], ex, (*x)[0]); + answer = pmod((*x)[4], ex, (*x)[1]); + answer = pmod((*x)[4], ex, (*x)[2]); + answer = pmod((*x)[4], ex, (*x)[3]); + } + } + + /* + * return duration + */ + end = runtime(); + return end-start; +} + + +/* + * pow_ratio - ratio of rates of 1st and 2nd pmod algorithms + * + * given: + * len length in BASEB-bit words to pmod + * + * return: + * ratio of (1st / 2nd) algorithm rates + * + * When want to determine a rate to a precision of 1 part in 1000. + * Most systems today return CPU time to at least 10 msec precision. + * So to get rates to that precision, we need to time loops to at + * least 1000 times as long as the precision (10 msec * 1000) + * which usually requires timing of loops that last 10 seconds or more. + * + * NOTE: This is an internal support function that is normally + * not called directly from the command line. Call the + * function best_pow2() instead. + */ +define pow_ratio(len) +{ + local mat x[5]; /* array of values for pow_loop to pmod */ + local mat one[5]; /* array if single BASEB-bit values */ + local baseb; /* calc word size in bits */ + local orig_cfg; /* caller configuration */ + local loops; /* number of pmod loops to time */ + local tlen; /* time to perform some number of loops */ + local tover; /* est of time for loop overhead */ + local alg1_rate; /* loop rate of 1st algorithm */ + local alg2_rate; /* loop rate of 2nd algorithm */ + local ex; /* exponent to use in pow_loop() */ + local i; + + /* + * firewall + */ + if (!isint(len) || len < 2) { + quit "pow_ratio: 1st arg: len is not an integer > 1"; + } + + /* + * remember the caller's config state + */ + orig_cfg = config("all"); + config("mul2", 0),; + config("sq2", 0),; + config("pow2", 0),; + config("redc2", 0),; + config("tilde", 0),; + + /* + * setup + */ + ex = 5; + + /* + * initialize x, the values we will pmod + * + * We want these tests to be repeatable as possible, so we will seed + * the PRNG in a deterministic way. + */ + baseb = config("baseb"); + srand(sha1(sha1(ex, baseb, config("version")))); + for (i=0; i < 5; ++i) { + /* force the values to be a full len words long */ + x[i] = ((1<<(((len-1) * baseb) + baseb-1)) | + randbit(((len-1) * baseb) + baseb-2)); + /* single BASEB-bit values */ + one[i] = 1; + } + + /* + * determine the number of loops needed to test 1st alg + */ + config("pow2", 2^31-1),; + config("redc2", 2^31-1),; + loops = 1/2; + do { + loops *= 2; + tlen = pow_loop(loops, &x, ex); + if (config("user_debug") > 3) { + printf("\t alg1 loops %d took %.3f sec\n", loops, tlen); + } + } while (tlen < 1.0); + + /* + * determine the 1st algorithm rate + */ + loops = max(1, ceil(loops * test_time / tlen)); + if (loops < 8) { + if (config("user_debug") > 1) { + printf(" we must expand loop test time to more than %d secs\n", + ceil(test_time * (8 / loops))); + } + loops = 8; + } + tlen = pow_loop(loops, &x, ex); + if (config("user_debug") > 3) { + printf("\t alg1 time = %.3f secs\n", tlen); + } + tover = pow_loop(loops, &one, ex); + if (config("user_debug") > 3) { + printf("\t alg1 overhead look %.3f secs\n", tover); + } + if (tlen <= tover) { + quit "pow_ratio: overhead >= loop time"; + } + alg1_rate = loops / (tlen - tover); + if (config("user_debug") > 2) { + printf("\tpmod alg1 rate = %.3f loopsets/sec\n", alg1_rate); + } + if (alg1_rate <= 0.0) { + quit "pow_ratio: alg1 rate was <= 0.0"; + } + + /* + * determine the number of loops needed to test 1st alg + */ + config("pow2", 2),; + config("redc2", 2^31-1),; + loops = 1/2; + do { + loops *= 2; + tlen = pow_loop(loops, &x, ex); + if (config("user_debug") > 3) { + printf("\t alg2 loops %d took %.3f sec\n", loops, tlen); + } + } while (tlen < 1.0); + + /* + * determine the 2nd algorithm rate + */ + loops = max(1, ceil(loops * test_time / tlen)); + if (loops < 8) { + if (config("user_debug") > 1) { + printf(" we must expand loop test time to more than %d secs\n", + ceil(test_time * (8 / loops))); + } + loops = 8; + } + tlen = pow_loop(loops, &x, ex); + if (config("user_debug") > 3) { + printf("\t alg2 time = %.3f secs\n", tlen); + } + tover = pow_loop(loops, &one, ex); + if (config("user_debug") > 3) { + printf("\t alg2 overhead look %.3f secs\n", tover); + } + if (tlen <= tover) { + quit "pow_ratio: overhead >= loop time"; + } + alg2_rate = loops / (tlen - tover); + if (config("user_debug") > 2) { + printf("\tpmod alg2 rate = %.3f loopsets/sec\n", alg2_rate); + } + if (alg2_rate <= 0.0) { + quit "pow_ratio: alg2 rate was <= 0.0"; + } + + /* + * restore old config + */ + config("all", orig_cfg),; + + /* + * return alg1 / alg2 rate ratio + */ + return (alg1_rate / alg2_rate); +} + + +/* + * best_pow2 - determine the best config("pow2") parameter w/o REDC2 + * + * NOTE: Due to precision problems with CPU measurements, it is not + * unusual for the output of this function to vary slightly + * from run to run. + * + * NOTE: This function is designed to take a long time to run. + * We recommend setting: + * + * config("user_debug", 2) + * + * so that yon can watch the progress of this function. + */ +define best_pow2() +{ + local ratio; /* previously calculated alg1/alg2 ratio */ + local low; /* low loop value tested */ + local high; /* low loop value tested */ + local expand; /* how fast to expand the length */ + local looped; /* 1 ==> we have expanded lengths before */ + + /* + * setup + */ + test_time = 15.0; + if (config("user_debug") > 0) { + printf("will start with loop test time of %d secs\n", test_time); + } + + /* + * firewall - must have a >1.02 ratio for the initial length + * + * We select 1.02 because of the precision of the CPU timing. We + * want to firt move into an area where the 1st algoritm clearly + * dominates. + */ + low = 4; + high = 4; + do { + high *= 4; + if (config("user_debug") > 0) { + printf("testing pmod alg1/alg2 ratio for len = %d\n", high); + } + ratio = pow_ratio(high); + if (config("user_debug") > 1) { + printf(" pmod alg1/alg2 ratio = %.3f\n", ratio); + if (ratio > 1.0 && ratio <= 1.02) { + printf(" while alg1 is slightly better than alg2, it is not clearly better\n"); + } + } + } while (ratio <= 1.02); + if (config("user_debug") > 0) { + printf("starting the pow2 search above %d\n", high); + } + + /* + * expand lengths until the ratio flips + */ + looped = 0; + do { + /* + * determine the paramters of the next ratio test + * + * We will multiplicatively expand our test level until + * the ratio drops below 1.0. + * + * NOTE: At low lengths, the ratios seen to be very small + * so we force an expansion of 4 to speed us on our + * way to larger lengths. At these somewhat larger + * lengths, the ratios usually don't get faster than + * 1.25, so we need to expand force a more rapid + * expansion than normal. At lengths longer than + * 2k, the time to test becomes very long, so we + * want to slow down at these higher lengths. + */ + expand = 2; + if (looped) { + low = high; + } + high *= expand; + if (config("user_debug") > 1) { + printf(" expand the next test range by a factor of %d\n", + expand); + } + + /* + * determine the alg1/alg2 test ratio for this new length + */ + if (high >= 2^31) { + quit "best_pow2: tests imply config(\"pow2\") should be >= 2^31"; + } + if (config("user_debug") > 0) { + printf("testing pmod alg1/alg2 ratio for len = %d\n", high); + } + ratio = pow_ratio(high); + if (config("user_debug") > 1) { + printf(" pmod alg1/alg2 ratio = %.3f\n", ratio); + } + looped = 1; + } while (ratio >= 1.0); + if (config("user_debug") > 0) { + printf("alg1/alg2 ratio now < 1.0, starting binary search between %d and %d\n", + low, high); + } + + /* + * binary search between low and high, for where ratio is just under 1.0 + */ + while (low+1 < high) { + + /* try the mid-point */ + if (config("user_debug") > 0) { + printf("testing pmod alg1/alg2 ratio for len = %d\n", + int((low+high)/2)); + } + ratio = pow_ratio(int((low+high)/2)); + if (config("user_debug") > 1) { + printf(" pmod alg1/alg2 ratio = %.3f\n", ratio); + } + + /* bump lower range up if we went over */ + if (ratio >= 1.0) { + if (config("user_debug") > 2) { + printf("\tmove low from %d up to %d\n", + low, int((low+high)/2)); + } + low = int((low+high)/2); + + /* drop higher range down if we went under */ + } else { + if (config("user_debug") > 2) { + printf("\tmove high from %d down to %d\n", + high, int((low+high)/2)); + } + high = int((low+high)/2); + } + } + + /* + * return on the suggested config("pow2") value + */ + if (config("user_debug") > 0) { + printf("best value of config(\"pow2\") is %d\n", + (ratio >= 1.0) ? high : low); + } + return ((ratio >= 1.0) ? high : low); +} diff --git a/cal/regress.cal b/cal/regress.cal index 8b425a6..3f238d9 100644 --- a/cal/regress.cal +++ b/cal/regress.cal @@ -17,8 +17,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.26 $ - * @(#) $Id: regress.cal,v 29.26 2006/06/02 09:49:13 chongo Exp $ + * @(#) $Revision: 29.29 $ + * @(#) $Id: regress.cal,v 29.29 2006/06/11 07:07:23 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/regress.cal,v $ * * Under source code control: 1990/02/15 01:50:36 @@ -404,14 +404,14 @@ define test_config() '512: config("trace") == 0'); vrfy(config("maxprint") == 16, '513: config("maxprint") == 16'); - vrfy(config("mul2") == 20, - '514: config("mul2") == 20'); - vrfy(config("sq2") == 20, - '515: config("sq2") == 20'); - vrfy(config("pow2") == 40, - '516: config("pow2") == 40'); - vrfy(config("redc2") == 50, - '517: config("redc2") == 50'); + vrfy(config("mul2") == 1780, + '514: config("mul2") == 1780'); + vrfy(config("sq2") == 3388, + '515: config("sq2") == 3388'); + vrfy(config("pow2") == 176, + '516: config("pow2") == 176'); + vrfy(config("redc2") == 220, + '517: config("redc2") == 220'); vrfy(config("tilde"), '518: config("tilde")'); vrfy(config("tab"), @@ -5226,6 +5226,11 @@ define test_is() local square; /* square of an odd prime */ local string; /* string */ local com; /* complex value */ + local rndint; /* a random integer */ + local rndexp; /* a random exponent */ + local rndval; /* rndint ^ rndexp */ + local i; /* integer value */ + local ok; /* 1 ==> issq() tests were OK, 0 ==> failure */ print '5900: Beginning test_is'; @@ -6163,15 +6168,75 @@ define test_is() vrfy(istype(matrix,odd) == 0, '6661: istype(matrix,odd) == 0'); vrfy(istype(a,odd) == 0, '6662: istype(a,odd) == 0'); + /* + * perform more extensive issq() testing + */ + ok = 1; + for (i=0; i < 256; ++i) { + /* rndval will be a square - even powers>0 of x>1 */ + rndexp = random(1, 16) * 2; + rndint = random(2, 4294967296); + if (issq(rndint)) { + ++rndint; + } + rndval = rndint ^ rndexp; + if (issq(rndval) == 0) { + prob(strprintf("issq(%d^%d) returned 0", + rndint, rndexp)); + ok = 0; + } + } + if (ok) { + print '6663: issq() on 256 squares'; + } else { + print '****: failure(s): 6663: faiissq() on 256 squares'; + } + for (i=0; i < 256; ++i) { + /* rndval will not be a square - 1 + even powers>0 of x>1 */ + rndexp = random(1, 16) * 2; + rndint = random(2, 4294967296); + rndval = rndint ^ rndexp; + if (issq(rndval+1) != 0) { + prob(strprintf("issq(%d^%d)+1 returned non-zero", + rndint, rndexp)); + ok = 0; + } + } + if (ok) { + print '6664: issq() on 256 squares+1'; + } else { + print '****: failure(s): 6664: issq() on 256 squares+1'; + } + print '6664: issq() on 256 squares+1'; + for (i=0; i < 256; ++i) { + /* rndval will not be a square - odd powers>0 of x>1 */ + rndexp = (random(1, 16) * 2) + 1; + rndint = random(2, 4294967296); + if (issq(rndint)) { + ++rndint; + } + rndval = rndint ^ rndexp; + if (issq(rndval) != 0) { + prob(strprintf("issq(%d^%d) returned non-zero", + rndint, rndexp)); + ok = 0; + } + } + if (ok) { + print '6665: issq() on 256 non-squares'; + } else { + print '****: failure(s): 6665: issq() on 256 non-squares'; + } + /* * cleanup */ blkfree("blk5900"); - print '6663: blkfree("blk5900")'; + print '6666: blkfree("blk5900")'; fclose(ofd); - print '6664: fclose(ofd)'; + print '6667: fclose(ofd)'; - print '6665: Ending test_is'; + print '6668: Ending test_is'; } print '168: test_is()'; @@ -7847,7 +7912,26 @@ read -once varargs; print '9827: read -once varargs'; read -once qtime; print '9828: read -once qtime'; -print '9829: Ending read of selected calc resource files'; +read -once chi; +print '9829: read -once chi'; +read -once intfile; +print '9830: read -once intfile'; +read -once lucas; +print '9831: read -once lucas'; +read -once lucas_tbl; +print '9832: read -once lucas_tbl'; +read -once natnumset; +print '9833: read -once natnumset'; +read -once repeat; +print '9834: read -once repeat'; +read -once screen; +print '9835: read -once screen'; +read -once linear; +print '9836: read -once linear'; +print '9837: skipping read -once beer.cal because it is an infinite loop'; +print '9838: skipping read -once hello.cal because it is an infinite loop'; +print '9839: skipping read -once xx_print.cal because it is a printing demo'; +print '9840: Ending read of selected calc resource files'; /* diff --git a/cal/test4100.cal b/cal/test4100.cal index 8be4200..cc7625d 100644 --- a/cal/test4100.cal +++ b/cal/test4100.cal @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.2 $ - * @(#) $Id: test4100.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $ + * @(#) $Revision: 29.3 $ + * @(#) $Id: test4100.cal,v 29.3 2006/06/10 20:19:20 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/test4100.cal,v $ * * Under source code control: 1996/03/13 03:53:22 @@ -316,8 +316,8 @@ define powtimes(str, N1, N2, n, verbose) mat B[n]; v = olen(N1); - cp = config("pow2", 1); - crc = config("redc2", 1); + cp = config("pow2", 2); + crc = config("redc2", 2); /* initialize redc and lastmod info */ @@ -346,7 +346,7 @@ define powtimes(str, N1, N2, n, verbose) for (i = 0; i < n; i++) z4 += rcpow(Ar[i], B[i], v); trcsmall = round(runtime() - t, 4); - config("redc2", 1); + config("redc2", 2); t = runtime(); for (i = 0; i < n; i++) z5 += rcpow(Ar[i], B[i], v); diff --git a/codegen.c b/codegen.c index 488120c..d11a771 100644 --- a/codegen.c +++ b/codegen.c @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.18 $ - * @(#) $Id: codegen.c,v 29.18 2006/06/03 22:47:28 chongo Exp $ + * @(#) $Revision: 29.20 $ + * @(#) $Id: codegen.c,v 29.20 2006/06/11 07:25:14 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/codegen.c,v $ * * Under source code control: 1990/02/15 01:48:13 @@ -1953,7 +1953,8 @@ getreference(void) switch(gettoken()) { case T_ANDAND: - scanerror(T_NULL, "Non-variable operand for &"); + scanerror(T_NULL, "&& used as prefix operator"); + /*FALLTHRU*/ case T_AND: type = getreference(); addop(OP_PTR); @@ -2108,6 +2109,19 @@ getterm(void) type = getidexpr(TRUE, 0); break; + case T_MULT: + (void) getterm(); + addop(OP_DEREF); + type = 0; + break; + + case T_POWER: /* '**' or '^' */ + (void) getterm(); + addop(OP_DEREF); + addop(OP_DEREF); + type = 0; + break; + case T_GLOBAL: if (gettoken() != T_SYMBOL) { scanerror(T_NULL, "Global id expected"); diff --git a/config.c b/config.c index 4b68de3..e746cf2 100644 --- a/config.c +++ b/config.c @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.17 $ - * @(#) $Id: config.c,v 29.17 2006/05/19 15:26:10 chongo Exp $ + * @(#) $Revision: 29.20 $ + * @(#) $Id: config.c,v 29.20 2006/06/11 00:08:56 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/config.c,v $ * * Under source code control: 1991/07/20 00:21:56 @@ -97,6 +97,7 @@ NAMETYPE configs[] = { {"compile_custom", CONFIG_COMPILE_CUSTOM}, {"allow_custom", CONFIG_ALLOW_CUSTOM}, {"version", CONFIG_VERSION}, + {"baseb", CONFIG_BASEB}, {NULL, 0} }; @@ -159,7 +160,8 @@ CONFIG oldstd = { /* backward compatible standard configuration */ FALSE, /* compiled without -DCUSTOM */ #endif &allow_custom, /* *TRUE=> custom functions are enabled */ - NULL /* version */ + NULL, /* version */ + BASEB, /* base for calculations */ }; CONFIG newstd = { /* new non-backward compatible configuration */ MODE_INITIAL, /* current output mode */ @@ -216,7 +218,8 @@ CONFIG newstd = { /* new non-backward compatible configuration */ FALSE, /* compiled without -DCUSTOM */ #endif &allow_custom, /* *TRUE=> custom functions are enabled */ - NULL /* version */ + NULL, /* version */ + BASEB, /* base for calculations */ }; CONFIG *conf = NULL; /* loaded in at startup - current configuration */ @@ -527,7 +530,7 @@ setconfig(int type, VALUE *vp) break; case CONFIG_MUL2: - if (getlen(vp, &len)) { + if (getlen(vp, &len) || len < 0 || len == 1) { math_error("Bad value for mul2"); /*NOTREACHED*/ } @@ -537,7 +540,7 @@ setconfig(int type, VALUE *vp) break; case CONFIG_SQ2: - if (getlen(vp, &len)) { + if (getlen(vp, &len) || len < 0 || len == 1) { math_error("Bad value for sq2"); /*NOTREACHED*/ } @@ -547,7 +550,7 @@ setconfig(int type, VALUE *vp) break; case CONFIG_POW2: - if (getlen(vp, &len)) { + if (getlen(vp, &len) || len < 0 || len == 1) { math_error("Bad value for pow2"); /*NOTREACHED*/ } @@ -557,7 +560,7 @@ setconfig(int type, VALUE *vp) break; case CONFIG_REDC2: - if (getlen(vp, &len)) { + if (getlen(vp, &len) || len < 0 || len == 1) { math_error("Bad value for redc2"); /*NOTREACHED*/ } @@ -899,6 +902,10 @@ setconfig(int type, VALUE *vp) math_error("The version config parameter is read-only"); /*NOTREACHED*/ + case CONFIG_BASEB: + math_error("The baseb config parameter is read-only"); + /*NOTREACHED*/ + default: math_error("Setting illegal config parameter"); /*NOTREACHED*/ @@ -1110,20 +1117,12 @@ config_value(CONFIG *cfg, int type, VALUE *vp) break; case CONFIG_TILDE: - if (cfg->tilde_ok) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->tilde_ok ? 1 : 0); + break; case CONFIG_TAB: - if (cfg->tab_ok) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->tab_ok ? 1 : 0); + break; case CONFIG_QUOMOD: i = cfg->quomod; @@ -1162,20 +1161,12 @@ config_value(CONFIG *cfg, int type, VALUE *vp) break; case CONFIG_LEADZERO: - if (cfg->leadzero) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->leadzero ? 1 : 0); + break; case CONFIG_FULLZERO: - if (cfg->fullzero) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->fullzero ? 1 : 0); + break; case CONFIG_MAXSCAN: i = cfg->maxscancount; @@ -1196,12 +1187,8 @@ config_value(CONFIG *cfg, int type, VALUE *vp) break; case CONFIG_BLKVERBOSE: - if (cfg->blkverbose) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->blkverbose ? 1 : 0); + break; case CONFIG_BLKBASE: vp->v_type = V_STR; @@ -1236,12 +1223,8 @@ config_value(CONFIG *cfg, int type, VALUE *vp) break; case CONFIG_VERBOSE_QUIT: - if (cfg->verbose_quit) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->verbose_quit ? 1 : 0); + break; case CONFIG_CTRL_D: vp->v_type = V_STR; @@ -1272,40 +1255,24 @@ config_value(CONFIG *cfg, int type, VALUE *vp) return; case CONFIG_WINDOWS: - if (cfg->windows) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->windows ? 1 : 0); + break; case CONFIG_CYGWIN: - if (cfg->cygwin) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->cygwin ? 1 : 0); + break; case CONFIG_COMPILE_CUSTOM: - if (cfg->compile_custom) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (cfg->compile_custom ? 1 : 0); + break; case CONFIG_ALLOW_CUSTOM: /* firewall */ if (cfg->allow_custom == NULL) { cfg->allow_custom = &allow_custom; } - if (*(cfg->allow_custom)) { - vp->v_num = itoq(1); - } else { - vp->v_num = itoq(0); - } - return; + i = (*(cfg->allow_custom) ? 1 : 0); + break; case CONFIG_VERSION: vp->v_type = V_STR; @@ -1316,6 +1283,10 @@ config_value(CONFIG *cfg, int type, VALUE *vp) } return; + case CONFIG_BASEB: + i = BASEB; + break; + default: math_error("Getting illegal CONFIG element"); /*NOTREACHED*/ @@ -1420,5 +1391,7 @@ config_cmp(CONFIG *cfg1, CONFIG *cfg2) (cfg1->version == NULL && cfg2->version != NULL) || (cfg1->version != NULL && cfg2->version == NULL) || (cfg1->version != NULL && cfg2->version != NULL && - strcmp(cfg1->version, cfg2->version) != 0); + strcmp(cfg1->version, cfg2->version) != 0) || + + cfg1->baseb != cfg2->baseb; } diff --git a/config.h b/config.h index d2f4d1a..71aabca 100644 --- a/config.h +++ b/config.h @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.17 $ - * @(#) $Id: config.h,v 29.17 2004/02/25 23:56:13 chongo Exp $ + * @(#) $Revision: 29.18 $ + * @(#) $Id: config.h,v 29.18 2006/06/06 07:17:02 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/config.h,v $ * * Under source code control: 1995/11/01 22:20:17 @@ -94,6 +94,7 @@ #define CONFIG_CYGWIN 40 #define CONFIG_COMPILE_CUSTOM 41 #define CONFIG_ALLOW_CUSTOM 42 +#define CONFIG_BASEB 43 /* @@ -162,6 +163,7 @@ struct config { BOOL compile_custom; /* TRUE => compiled with -DCUSTOM */ BOOL *allow_custom; /* ptr to if custom functions are allowed */ char *version; /* calc version string */ + int baseb; /* base for calculations */ }; typedef struct config CONFIG; diff --git a/func.c b/func.c index 00a5ac8..54f89d7 100644 --- a/func.c +++ b/func.c @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.25 $ - * @(#) $Id: func.c,v 29.25 2006/05/21 07:28:54 chongo Exp $ + * @(#) $Revision: 29.26 $ + * @(#) $Id: func.c,v 29.26 2006/06/11 00:08:56 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/func.c,v $ * * Under source code control: 1990/02/15 01:48:15 @@ -871,7 +871,7 @@ f_nextcand(int count, NUMBER **vals) ans->num = tmp; return ans; } - return qlink(&_qzero_);; + return qlink(&_qzero_); } diff --git a/hash.c b/hash.c index 2869417..6f840ff 100644 --- a/hash.c +++ b/hash.c @@ -17,8 +17,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.8 $ - * @(#) $Id: hash.c,v 29.8 2006/05/19 15:26:10 chongo Exp $ + * @(#) $Revision: 29.9 $ + * @(#) $Id: hash.c,v 29.9 2006/06/06 07:17:02 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/hash.c,v $ * * Under source code control: 1995/11/23 05:13:11 @@ -995,6 +995,7 @@ hash_value(int type, void *v, HASH *state) state = hash_bool(type, FALSE, state); } state = hash_str(type, value->v_config->version, state); + state = hash_int(type, value->v_config->baseb, state); break; case V_HASH: diff --git a/help/address b/help/address index 6cc3ba2..91a64ca 100644 --- a/help/address +++ b/help/address @@ -38,7 +38,7 @@ DESCRIPTION &X with that component or element depends only on the continued existence of the matrix or object. For example, after - > mat A[3] + ; mat A[3] the addresses &A[0], &A[1], &A[2] locate the three elements of the matrix specified by A until another value is assigned to A, etc. @@ -60,15 +60,15 @@ DESCRIPTION results refer to octets in the same block or existing components of the same matrix or object. For example, immediately after - > mat A[10] - > p = &A[5] + ; mat A[10] + ; p = &A[5] it is permitted to use expressions like p + 4, p - 5, p++ . Strings defined literally have fixed addresses, e.g., after - > p = &"abc" - > A = "abc" + ; p = &"abc" + ; A = "abc" the address &*A of the value of A will be equal to p. @@ -78,7 +78,7 @@ DESCRIPTION be useable only while the variables retain these defined values. For example, after - > B = C = strcat("a", "bc"); + ; B = C = strcat("a", "bc"); &*B and &*C will be different. If p is defined by p = &*B, p should not be used after a new value is assigned to B, or B ceases to exist, @@ -91,9 +91,9 @@ DESCRIPTION so long as the number remains associated with at least one function or lvalue. For example, after - > x = 27; - > y = 3 * 9; - > define f(a) = 27 + a; + ; x = 27; + ; y = 3 * 9; + ; define f(a) = 27 + a; the three occurrences of 27 have the same address which may be displayed by any of &27, &*x, &*y and &f(0). If x and y are assigned @@ -109,13 +109,13 @@ DESCRIPTION non-zero value for a will be assigned to different addresses as can be seen from printing &*A, &*B, &*C after - > A = f(2); B = f(2); C = f(2); + ; A = f(2); B = f(2); C = f(2); (the case of f(0) is exceptional since 27 + 0 simply copies the 27 rather than creating a new number value). Here it is clearly more efficient to use - > A = B = C = f(2); + ; A = B = C = f(2); which, not only performs the addition in f() only once, but stores the number values for A, B and C at the same address. @@ -160,7 +160,7 @@ LINK LIBRARY SEE ALSO dereference, isptr -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -176,8 +176,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: address,v 29.4 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: address,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/address,v $ ## ## Under source code control: 1997/09/06 20:03:34 diff --git a/help/blkcpy b/help/blkcpy index 3e52014..4e420f4 100644 --- a/help/blkcpy +++ b/help/blkcpy @@ -19,7 +19,7 @@ TYPES DESCRIPTION A call to: - blkcpy(dst, src, num, dsi, ssi) + blkcpy(dst, src, num, dsi, ssi) attempts to copy 'num' consecutive items (octets or values) starting from the source item 'src' with index 'ssi'. By default, 'num' @@ -27,7 +27,7 @@ DESCRIPTION A call to: - copy(src, dst, ssi, num, dsi) + copy(src, dst, ssi, num, dsi) does the same thing, but with a different arg order. @@ -40,30 +40,30 @@ DESCRIPTION The following pairs of source-type, destination-type are permitted: - block to - int - block - matrix - file + block to + int + block + matrix + file - matrix to - block - matrix - list + matrix to + block + matrix + list - string to - block - file + string to + block + file - list to - list - matrix + list to + list + matrix - file to - block + file to + block - int to - block + int to + block In the above table, int refers to integer values. However if a rational value is supplied, only the numerator is copied. @@ -79,11 +79,11 @@ DESCRIPTION sufficient memory allocated for the copying. For example, to copy a matrix M of size 100 to a newly created list, one may use: - L = makelist(100); - copy(M, L); + ; L = makelist(100); + ; copy(M, L); or: - L = makelist(100); - blkcpy(L, M); + ; L = makelist(100); + ; blkcpy(L, M); For copying from a block B (named or unnamed), the total number of octets available for copying is taken to the the datalen for that block, @@ -114,7 +114,6 @@ EXAMPLE ; B chunksize = 256, maxsize = 256, datalen = 4 01020304 - > ; blkcpy(B,A) ; B chunksize = 256, maxsize = 256, datalen = 8 @@ -191,7 +190,7 @@ LINK LIBRARY SEE ALSO blk, mat, file, list, str -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -207,8 +206,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: blkcpy,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: blkcpy,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/blkcpy,v $ ## ## Under source code control: 1997/04/05 14:08:50 diff --git a/help/calc_tty b/help/calc_tty index 6d2e911..12389ee 100644 --- a/help/calc_tty +++ b/help/calc_tty @@ -13,9 +13,9 @@ DESCRIPTION may occur when activity is resumed by an fg command after a ctrl-Z interrupt, or by any of the three commands: - > !stty echo - > !stty -cbreak - > !stty echo -cbreak + ; !stty echo + ; !stty -cbreak + ; !stty echo -cbreak EXAMPLE ; calc_tty(); @@ -26,7 +26,7 @@ LIBRARY SEE ALSO none -## Copyright (C) 2000 Ernest Bowen +## Copyright (C) 2000-2006 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 @@ -42,8 +42,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.2 $ -## @(#) $Id: calc_tty,v 29.2 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.3 $ +## @(#) $Id: calc_tty,v 29.3 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/calc_tty,v $ ## ## Under source code control: 2000/12/14 01:33:00 diff --git a/help/command b/help/command index 7dcf757..973f08a 100644 --- a/help/command +++ b/help/command @@ -19,26 +19,26 @@ Command sequence define function(params) { body } define function(params) = expression - This first form defines a full function which can consist - of declarations followed by many statements which implement - the function. + This first form defines a full function which can consist + of declarations followed by many statements which implement + the function. - The second form defines a simple function which calculates - the specified expression value from the specified parameters. - The expression cannot be a statement. However, the comma - and question mark operators can be useful. Examples of - simple functions are: + The second form defines a simple function which calculates + the specified expression value from the specified parameters. + The expression cannot be a statement. However, the comma + and question mark operators can be useful. Examples of + simple functions are: - define sumcubes(a, b) = a^3 + b^3 - define pimod(a) = a % pi() - define printnum(a, n, p) - { - if (p == 0) { - print a: "^": n, "=", a^n; - } else { - print a: "^": n, "mod", p, "=", pmod(a,n,p); - } + define sumcubes(a, b) = a^3 + b^3 + define pimod(a) = a % pi() + define printnum(a, n, p) + { + if (p == 0) { + print a: "^": n, "=", a^n; + } else { + print a: "^": n, "mod", p, "=", pmod(a,n,p); } + } read calc commands @@ -48,45 +48,45 @@ Command sequence read filename read -once filename - This reads definitions from the specified calc resource filename. + This reads definitions from the specified calc resource filename. - In the 1st and 2nd forms, if var is a global variable string - value, then the value of that variable is used as a filename. + In the 1st and 2nd forms, if var is a global variable string + value, then the value of that variable is used as a filename. - The following is equivalent to read lucas.cal or read "lucas.cal": + The following is equivalent to read lucas.cal or read "lucas.cal": - global var = "lucas.cal"; - read $var; + global var = "lucas.cal"; + read $var; - In the 3rd or 4th forms, the filename argument is treated - as a literal string, not a variable. In these forms, the - name can be quoted if desired. + In the 3rd or 4th forms, the filename argument is treated + as a literal string, not a variable. In these forms, the + name can be quoted if desired. - The calculator uses the CALCPATH environment variable to - search through the specified directories for the filename, - similarly to the use of the PATH environment variable. - If CALCPATH is not defined, then a default path which is - usually ":/usr/local/lib/calc" is used. + The calculator uses the CALCPATH environment variable to + search through the specified directories for the filename, + similarly to the use of the PATH environment variable. + If CALCPATH is not defined, then a default path which is + usually ":/usr/local/lib/calc" is used. - The ".cal" extension is defaulted for input files, so that - if "filename" is not found, then "filename.cal" is then - searched for. The contents of the filename are command - sequences which can consist of expressions to evaluate or - functions to define, just like at the top level command level. + The ".cal" extension is defaulted for input files, so that + if "filename" is not found, then "filename.cal" is then + searched for. The contents of the filename are command + sequences which can consist of expressions to evaluate or + functions to define, just like at the top level command level. - When -once is given, the read command acts like the regular - read expect that it will ignore filename if is has been - previously read. + When -once is given, the read command acts like the regular + read expect that it will ignore filename if is has been + previously read. - The read -once form is particularly useful in a resource - file that needs to read a 2nd resource file. By using the - READ -once command, one will not reread that 2nd resource - file, nor will once risk entering into a infinite READ loop - (where that 2nd resource file directly or indirectly does - a READ of the first resource file). + The read -once form is particularly useful in a resource + file that needs to read a 2nd resource file. By using the + READ -once command, one will not reread that 2nd resource + file, nor will once risk entering into a infinite READ loop + (where that 2nd resource file directly or indirectly does + a READ of the first resource file). - If the -m mode disallows opening of files for reading, - this command will be disabled. + If the -m mode disallows opening of files for reading, + this command will be disabled. write calc commands @@ -94,29 +94,29 @@ Command sequence write $var write filename - This writes the values of all global variables to the - specified filename, in such a way that the file can be - later read in order to recreate the variable values. - For speed reasons, values are written as hex fractions. - This command currently only saves simple types, so that - matrices, lists, and objects are not saved. Function - definitions are also not saved. + This writes the values of all global variables to the + specified filename, in such a way that the file can be + later read in order to recreate the variable values. + For speed reasons, values are written as hex fractions. + This command currently only saves simple types, so that + matrices, lists, and objects are not saved. Function + definitions are also not saved. - In the 1st form, if var is a global variable string - value, then the value of that variable is used as a filename. + In the 1st form, if var is a global variable string + value, then the value of that variable is used as a filename. - The following is equivalent to write dump.out or - write "dump.out": + The following is equivalent to write dump.out or + write "dump.out": - global var = "dump.out"; - write $var; + global var = "dump.out"; + write $var; - In the 2nd form, the filename argument is treated as a literal - string, not a variable. In this form, the name can be quoted - if desired. + In the 2nd form, the filename argument is treated as a literal + string, not a variable. In this form, the name can be quoted + if desired. - If the -m mode disallows opening of files for writing, - this command will be disabled. + If the -m mode disallows opening of files for writing, + this command will be disabled. quit or exit @@ -126,36 +126,35 @@ Command sequence exit exit string - The action of these commands depends on where they are used. - At the interactive level, they will cause calc it edit. - This is the normal way to leave the calculator. In any - other use, they will stop the current calculation as if - an error had occurred. + The action of these commands depends on where they are used. + At the interactive level, they will cause calc it edit. + This is the normal way to leave the calculator. In any + other use, they will stop the current calculation as if + an error had occurred. - If a string is given, then the string is printed as the reason - for quitting, otherwise a general quit message is printed. - The routine name and line number which executed the quit is - also printed in either case. + If a string is given, then the string is printed as the reason + for quitting, otherwise a general quit message is printed. + The routine name and line number which executed the quit is + also printed in either case. - Exit is an alias for quit. + Exit is an alias for quit. - Quit is useful when a routine detects invalid arguments, - in order to stop a calculation cleanly. For example, - for a square root routine, an error can be given if the - supplied parameter was a negative number, as in: + Quit is useful when a routine detects invalid arguments, + in order to stop a calculation cleanly. For example, + for a square root routine, an error can be given if the + supplied parameter was a negative number, as in: - define mysqrt(n) - { - if (! isnum(n)) - quit "non-numeric argument"; - if (n < 0) - quit "Negative argument"; - return sqrt(n); - } - - See 'more information about abort and quit' below for - more information. + define mysqrt(n) + { + if (! isnum(n)) + quit "non-numeric argument"; + if (n < 0) + quit "Negative argument"; + return sqrt(n); + } + See 'more information about abort and quit' below for + more information. abort @@ -163,12 +162,12 @@ Command sequence abort abort string - This command behaves like QUIT except that it will attempt - to return to the interactive level if permitted, otherwise - calc exit. + This command behaves like QUIT except that it will attempt + to return to the interactive level if permitted, otherwise + calc exit. - See 'more information about abort and quit' below for - more information. + See 'more information about abort and quit' below for + more information. change current directory @@ -176,45 +175,45 @@ Command sequence cd cd dir - Change the current directory to 'dir'. If 'dir' is ommitted, - change the current directory to the home directory, if $HOME - is set in the environment. + Change the current directory to 'dir'. If 'dir' is ommitted, + change the current directory to the home directory, if $HOME + is set in the environment. show information ---------------- show item - This command displays some information where 'item' is - one of the following: + This command displays some information where 'item' is + one of the following: - blocks unfreed named blocks - builtin built in functions - config config parameters and values - constants cache of numeric constants - custom custom functions if calc -C was used - errors new error-values created - files open files, file position and sizes - function user-defined functions - globaltypes global variables - objfunctions possible object functions - objtypes defined objects - opcodes func internal opcodes for function `func' - sizes size in octets of calc value types - realglobals numeric global variables - statics unscoped static variables - numbers calc number cache - redcdata REDC data defined - strings calc string cache - literals calc literal cache + blocks unfreed named blocks + builtin built in functions + config config parameters and values + constants cache of numeric constants + custom custom functions if calc -C was used + errors new error-values created + files open files, file position and sizes + function user-defined functions + globaltypes global variables + objfunctions possible object functions + objtypes defined objects + opcodes func internal opcodes for function `func' + sizes size in octets of calc value types + realglobals numeric global variables + statics unscoped static variables + numbers calc number cache + redcdata REDC data defined + strings calc string cache + literals calc literal cache - Only the first 4 characters of item are examined, so: + Only the first 4 characters of item are examined, so: - show globals - show global - show glob + show globals + show global + show glob - do the same thing. + do the same thing. calc help @@ -222,25 +221,24 @@ Command sequence help $var help name - This displays a help related to 'name' or general - help of none is given. + This displays a help related to 'name' or general + help of none is given. - In the 1st form, if var is a global variable string - value, then the value of that variable is used as a name. + In the 1st form, if var is a global variable string + value, then the value of that variable is used as a name. - The following is equivalent to help command or help "command": + The following is equivalent to help command or help "command": - global var = "command"; - help $var; + global var = "command"; + help $var; - In the 2nd form, the filename argument is treated as a literal - string, not a variable. In this form, the name can be quoted - if desired. + In the 2nd form, the filename argument is treated as a literal + string, not a variable. In this form, the name can be quoted + if desired. =-= - more information about abort and quit ===================================== @@ -291,7 +289,7 @@ Command sequence after statment #1 start statment #2 abort from a() - > <==== calc interactive prompt + ; <==== calc interactive prompt because the '-i' calc causes ABORT to drop into an interactive prompt. However typing a QUIT or ABORT @@ -321,21 +319,21 @@ Command sequence If one were to type in the contents of myfile.cal interactively, calc will produce: - > print "start of myfile.cal"; + ; print "start of myfile.cal"; start of myfile.cal - > define q() {quit "quit from q()"; print "end of q()"} + ; define q() {quit "quit from q()"; print "end of q()"} q() defined - > define a() {abort "abort from a()"} + ; define a() {abort "abort from a()"} a() defined - > x = 3; - > {print "start #1"; if (x > 1) q()} print "after #1"; + ; x = 3; + ; {print "start #1"; if (x > 1) q()} print "after #1"; start statment #1 quit from q() after statment #1 - > {print "start #2"; if (x > 1) a()} print "after #2"; + ; {print "start #2"; if (x > 1) a()} print "after #2"; start statment #2 abort from a() - > {print "start #3"; if (x > 1) quit "quit from 3rd statement"} + ; {print "start #3"; if (x > 1) quit "quit from 3rd statement"} start #3 quit from 3rd statement @@ -345,16 +343,14 @@ Command sequence The QUIT (after the if (x > 1) ...) will cause calc to exit because it was given at the interactive prompt level. - =-= - Also see the help topic: - statement flow control and declaration statements - usage how to invoke the calc command and calc -options + statement flow control and declaration statements + usage how to invoke the calc command and calc -options -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -370,8 +366,8 @@ Command sequence ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: command,v 29.3 2006/05/20 10:01:33 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: command,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/command,v $ ## ## Under source code control: 1991/07/21 04:37:17 diff --git a/help/config b/help/config index fc6120f..c9ca850 100644 --- a/help/config +++ b/help/config @@ -1,12 +1,24 @@ -Configuration parameters +NAME + config - configuration parameters - Configuration parameters affect how the calculator performs certain +SYNOPSIS + config(parameter [,value]) + +TYPES + parameter string + value int, string, config state + + return config state + +DESCRIPTION + The config() builtin affects how the calculator performs certain operations. Among features that are controlled by these parameters are the accuracy of some calculations, the displayed format of results, the choice from possible alternative algorithms, and whether or not debugging information is displayed. The parameters are read or set using the "config" built-in function; they remain in effect until their values are changed by a config or equivalent instruction. + The following parameters can be specified: "all" all configuration values listed below @@ -53,6 +65,7 @@ Configuration parameters "compile_custom" TRUE=>calc was compiled with custom functions "allow_custom" TRUE=>custom functions are enabled "version" Read-only calc version + "baseb" bits in calculation base, a read-only value The "all" config value allows one to save/restore the configuration set of values. The return of: @@ -120,9 +133,6 @@ Configuration parameters config("tilde", 0) disable roundoff tilde printing config("tab", "off") disable leading tab printing - -Detailed config descriptions - =-= config("trace", bitflag) @@ -254,16 +264,36 @@ Detailed config descriptions runs in a time of O(N^2). The second method is a recursive and complicated method which runs in a time of O(N^1.585). The argument for these parameters is the number of binary words at which the - second algorithm begins to be used. The minimum value is 2, and + second algorithm begins to be used. The minimum value is 2, and the maximum value is very large. If 2 is used, then the recursive algorithm is used all the way down to single digits, which becomes slow since the recursion overhead is high. If a number such as - 1000000 is used, then the recursive algorithm is never used, causing - calculations for large numbers to slow down. For a typical example - on a 386, the two algorithms are about equal in speed for a value - of 20, which is about 100 decimal digits. A value of zero resets - the parameter back to its default value. Usually there is no need - to change these parameters. + 1000000 is used, then the recursive algorithm is almost never used, + causing calculations for large numbers to slow down. + + Units refer to internal calculation digits where each digit + is BASEB bits in length. The value of BASEB is returned by + config("baseb"). + + The default value for config("sq2") is 3388. This default was + established on a 1.8GHz AMD 32-bit CPU of ~3406 BogoMIPS when + the two algorithms are about equal in speed. For that CPU test, + config("baseb") was 32. This means that by default numbers up to + (3388*32)+31 = 108447 bits in length (< 32645 decinal digits) use + the 1st algorithm, for squaring. + + The default value for config("mul2") is 1780. This default was + established on a 1.8GHz AMD 32-bit CPU of ~3406 BogoMIPS when + the two algorithms are about equal in speed. For that CPU test, + config("baseb") was 32. This means that by default numbers up to + (1779*32)+31 = 56927 bits in length (< 17137 decinal digits) use + the 1st algorithm, for multiplication. + + A value of zero resets the parameter back to their default values. + + The value of 1 and values < 0 are reserved for future use. + + Usually there is no need to change these parameters. =-= @@ -277,6 +307,23 @@ Detailed config descriptions which avoids divisions. The argument for pow2 is the size of the modulus at which the second algorithm begins to be used. + Units refer to internal calculation digits where each digit + is BASEB bits in length. The value of BASEB is returned by + config("baseb"). + + The default value for config("pow2") is 176. This default was + established on a 1.8GHz AMD 32-bit CPU of ~3406 BogoMIPS when + the two algorithms are about equal in speed. For that CPU test, + config("baseb") was 32. This means that by default numbers up to + (176*32)+31 = 5663 bits in length (< 1704 decinal digits) use the + 1st algorithm, for calculating powers modulo another number. + + A value of zero resets the parameter back to their default values. + + The value of 1 and values < 0 are reserved for future use. + + Usually there is no need to change these parameters. + =-= config("redc2", int) @@ -289,6 +336,23 @@ Detailed config descriptions O(N^1.585). The argument for redc2 is the size of the modulus at which the second algorithm begins to be used. + Units refer to internal calculation digits where each digit + is BASEB bits in length. The value of BASEB is returned by + config("baseb"). + + The default value for config("redc2") is 220. This default was + established as 5/4 (the historical ratio of config("pow2") to + config("pow2")) of the config("pow2") value. This means that if + config("baseb") is 32, then by default numbers up to (220*32)+31 = + 7071 bits in length (< 2128 decinal digits) use the REDC algorithm, + for calculating powers modulo another number. + + A value of zero resets the parameter back to their default values. + + The value of 1 and values < 0 are reserved for future use. + + Usually there is no need to change these parameters. + =-= config("tilde", boolean) @@ -560,11 +624,12 @@ Detailed config descriptions 3 During execution, allow calc standard resource files to output additional debugging information. - The value for config("resource_debug") in both oldstd and newstd is 3, - but if calc is invoked with the -d flag, its initial value is zero. - Thus, if calc is started without the -d flag, until config("resource_debug") - is changed, a message will be output when a function is defined - either interactively or during the reading of a file. + The value for config("resource_debug") in both oldstd and newstd + is 3, but if calc is invoked with the -d flag, its initial value + is zero. Thus, if calc is started without the -d flag, until + config("resource_debug") is changed, a message will be output when + a function is defined either interactively or during the reading of + a file. The name config("lib_debug") is equivalent to config("resource_debug") and is included for backward compatibility. @@ -601,7 +666,7 @@ Detailed config descriptions A quit of abort without an argument does not display a message when invoked at the interactive level. - By deafult, "verbose_quit" is false. + By default, "verbose_quit" is false. =-= @@ -756,7 +821,95 @@ Detailed config descriptions This config parameter is read-only and cannot be set. -## Copyright (C) 1999 Landon Curt Noll + =-= + + config("baseb") <== NOTE: This is a read-only config value + + Returns the number of bits in the fundamental base in which + internal calculations are performed. For example, a value of + 32 means that calc will perform many internal calculations in + base 2^32 with digits that are 32 bits in length. + + For libcalc programmers, this is the value of BASEB as defined + in the zmath.h header file. + + This config parameter is read-only and cannot be set. + +EXAMPLE + ; current_cfg = config("all"); + ; config("tilde", off),; + ; config("calc_debug", 15),; + ; config("all") == current_cfg + 0 + ; config("all", current_cfg),; + ; config("all") == current_cfg + 1 + + ; config("version") + "2.12.0" + + ; config("all") + mode "real" + mode2 "off" + display 20 + epsilon 0.00000000000000000001 + trace 0 + maxprint 16 + mul2 20 + sq2 20 + pow2 40 + redc2 50 + tilde 1 + tab 1 + quomod 0 + quo 2 + mod 0 + sqrt 24 + appr 24 + cfappr 0 + cfsim 8 + outround 24 + round 24 + leadzero 1 + fullzero 0 + maxscan 20 + prompt "; " + more ";; " + blkmaxprint 256 + blkverbose 0 + blkbase "hexadecimal" + blkfmt "hd_style" + resource_debug 3 + lib_debug 3 + calc_debug 0 + user_debug 0 + verbose_quit 0 + ctrl_d "virgin_eof" + program "calc" + basename "calc" + windows 0 + cygwin 0 + compile_custom 1 + allow_custom 0 + version "2.12.0" + baseb 32 + + ; display() + 20 + ; config("display", 50),; + ; display() + 50 + +LIMITS + none + +LINK LIBRARY + n/a + +SEE ALSO + usage, custom, custom_cal, usage, epsilon, display + +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -772,8 +925,8 @@ Detailed config descriptions ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.10 $ -## @(#) $Id: config,v 29.10 2004/07/27 23:45:52 chongo Exp $ +## @(#) $Revision: 29.15 $ +## @(#) $Id: config,v 29.15 2006/06/11 07:22:05 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/config,v $ ## ## Under source code control: 1991/07/21 04:37:17 diff --git a/help/define b/help/define index 3462d70..7f89565 100644 --- a/help/define +++ b/help/define @@ -30,17 +30,17 @@ DESCRIPTION For example, suppose a function f and a global variable A have been defined by: - define f(x) = (x = 3); - global mat A[3]; + ; define f(x) = (x = 3); + ; global mat A[3]; If g() is a function that evaluates to 2: - f(A[g()]); + ; f(A[g()]); assigns the value of A[2] to the parameter x and then assigns the value 3 to x: - f(`A[g()]); + ; f(`A[g()]); has essentially the effect of assigning A[2] as an lvalue to x and then assigning the value 3 to A[2]. (Very old versions of calc @@ -79,7 +79,7 @@ DESCRIPTION If the expr is omitted from an expression definition, as in: - define h() = ; + ; define h() = ; any call to the function will evaluate the arguments and return the null value. @@ -105,11 +105,11 @@ DESCRIPTION After fname has been defined, the definition may be removed by the command: - undefine fname + ; undefine fname The definitions of all user-defined functions may be removed by: - undefine * + ; undefine * If bit 0 of config("resource_debug") is set and the define command is at interactive level, a message saying that fname has been defined @@ -120,8 +120,8 @@ DESCRIPTION The identifiers used for the parameters in a function definition do not form part of the completed definition. For example, - define f(a,b) = a + b; - define g(alpha, beta) = alpha + beta; + ; define f(a,b) = a + b; + ; define g(alpha, beta) = alpha + beta; result in identical code for the functions f, g. @@ -129,8 +129,8 @@ DESCRIPTION function are displayed on completion of its definition, parameters being specified by names used in the definition. For example: - > config("trace", 8), - > define f(a,b) = a + b + ; config("trace", 8), + ; define f(a,b) = a + b 0: PARAMADDR a 2: PARAMADDR b 4: ADD @@ -140,7 +140,7 @@ DESCRIPTION The opcodes may also be displayed later using the show opcodes command; parameters will be specified by indices instead of by names. For example: - > show opco f + ; show opco f 0: PARAMADDR 0 2: PARAMADDR 1 4: ADD @@ -168,19 +168,19 @@ DESCRIPTION EXAMPLE ; define f(a,b) = 2*a + b; ; define g(alpha, beta) - >> { - >> local a, pi2; - >> - >> pi2 = 2 * pi(); - >> a = sin(alpha % pi2); - >> if (a > 0.0) { - >> return a*beta; - >> } - >> if (beta > 0.0) { - >> a *= cos(-beta % pi2); - >> } - >> return a; - >> } + ;; { + ;; local a, pi2; + ;; + ;; pi2 = 2 * pi(); + ;; a = sin(alpha % pi2); + ;; if (a > 0.0) { + ;; return a*beta; + ;; } + ;; if (beta > 0.0) { + ;; a *= cos(-beta % pi2); + ;; } + ;; return a; + ;; } LIMITS The number of arguments in a function-call cannot exceed 100. @@ -191,7 +191,7 @@ LIBRARY SEE ALSO param, variable, undefine, show -## Copyright (C) 2000 David I. Bell, Landon Curt Noll and Ernest Bowen +## Copyright (C) 2000-2006 David I. Bell, Landon Curt Noll and 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 @@ -207,8 +207,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: define,v 29.4 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: define,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/define,v $ ## ## diff --git a/help/dereference b/help/dereference index 5a57070..30603af 100644 --- a/help/dereference +++ b/help/dereference @@ -33,16 +33,17 @@ DESCRIPTION structure rather than the structure identified by X. For example, suppose B has been created by - mat B[3] = {1,2,3} + ; mat B[3] = {1,2,3} then - A = *B = {4,5,6} + + ; A = *B = {4,5,6} will assign the values 4,5,6 to the elements of a copy of B, which will then become the value of A, so that the values of A and B will be different. On the other hand, - A = B = {4,5,6} + ; A = B = {4,5,6} will result in A and B having the same value. @@ -51,9 +52,9 @@ DESCRIPTION The * operator may be iterated with suitable sequences of pointer-valued lvalues. For example, after - > global a, b, c; - > b = &a; - > c = &b; + ; global a, b, c; + ; b = &a; + ; c = &b; **c returns the lvalue a; ***c returns the value of a. @@ -81,7 +82,7 @@ LINK LIBRARY SEE ALSO address, isptr -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -97,8 +98,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: dereference,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: dereference,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/dereference,v $ ## ## Under source code control: 1997/09/06 20:03:34 diff --git a/help/digit b/help/digit index e331fbb..1edd9de 100644 --- a/help/digit +++ b/help/digit @@ -28,11 +28,11 @@ DESCRIPTION left of the "decimal" point; the digit d_n at position n contributes additively d_n * b^n to the value of x. For example, - d_2 d_1 d_0 . d_-1 d_-2 + ; d_2 d_1 d_0 . d_-1 d_-2 represents the number - d_2 * b^2 + d_1 * b + d0 + d_-1 * b^-1 + d_-2 * b^-2 + ; d_2 * b^2 + d_1 * b + d0 + d_-1 * b^-1 + d_-2 * b^-2 The sequence of digits has to be infinite if den(x) has a prime factor which is not a factor of the base b. In cases where the representation @@ -53,30 +53,30 @@ DESCRIPTION With base-b digits for x as explained above, the integer whose base-b representation is - b_n+k-1 b_n_k-2 ... b_n, + ; b_n+k-1 b_n_k-2 ... b_n, i.e. the k digits with last digit b_n, is given by - digit(b^-r * x, q, b^k) + ; digit(b^-r * x, q, b^k) if r and q satisfy n = q * b + r. EXAMPLE - > a = 123456.789 - > for (n = 6; n >= -6; n++) print digit(a, n),; print + ; a = 123456.789 + ; for (n = 6; n >= -6; n++) print digit(a, n),; print 0 1 2 3 4 5 6 7 8 9 0 0 0 - > for (n = 6; n >= -6; n--) print digit(a, n, 100),; print + ; for (n = 6; n >= -6; n--) print digit(a, n, 100),; print 0 0 0 0 12 34 56 78 90 0 0 0 0 - > for (n = 6; n >= -6; n--) print digit(a, n, 256),; print + ; for (n = 6; n >= -6; n--) print digit(a, n, 256),; print 0 0 0 0 1 226 64 201 251 231 108 139 67 - > for (n = 1; n >= -12; n++) print digit(10/7, n),; print - > 0 1 4 2 8 5 7 1 4 2 8 5 7 1 + ; for (n = 1; n >= -12; n++) print digit(10/7, n),; print + ; 0 1 4 2 8 5 7 1 4 2 8 5 7 1 - > print digit(10/7, -7e1000, 1e6) + ; print digit(10/7, -7e1000, 1e6) 428571 LIMITS @@ -92,7 +92,7 @@ LINK LIBRARY SEE ALSO bit -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -108,8 +108,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: digit,v 29.4 2000/12/17 12:27:58 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: digit,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/digit,v $ ## ## Under source code control: 1995/10/03 10:40:01 diff --git a/help/environment b/help/environment index da7abf3..28a0dec 100644 --- a/help/environment +++ b/help/environment @@ -21,7 +21,6 @@ Environment variables The CALCBINDINGS file searches the CALCPATH as well. - CALCRC On startup (unless -h or -q was given on the command @@ -105,8 +104,8 @@ Environment variables ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: environment,v 29.4 2006/05/07 07:22:20 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: environment,v 29.5 2006/06/10 13:01:09 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/environment,v $ ## ## Under source code control: 1991/07/23 05:47:25 diff --git a/help/fgetfield b/help/fgetfield index 7a39b55..f67336a 100644 --- a/help/fgetfield +++ b/help/fgetfield @@ -31,7 +31,7 @@ EXAMPLE ; fgetfield(f) "Beta" ; fgetfield(f) - > + ; freopen(f, "w") ; fputstr(f, " Alpha ", "Beta") ; freopen(f, "r") @@ -51,7 +51,7 @@ LINK LIBRARY SEE ALSO fgetstr, fputstr, fgets, fputs, fopen, files, fprintf -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -67,8 +67,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: fgetfield,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: fgetfield,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/fgetfield,v $ ## ## Under source code control: 1996/04/30 03:05:17 diff --git a/help/fgetstr b/help/fgetstr index 4146542..b86e43a 100644 --- a/help/fgetstr +++ b/help/fgetstr @@ -36,7 +36,6 @@ EXAMPLE "Gamma Delta" ; fgetstr(f) - > LIMITS none - XXX - is this correct? @@ -47,7 +46,7 @@ LINK LIBRARY SEE ALSO fputstr, fgetword, fgets, fputs, fopen, files, fprintf -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -63,8 +62,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: fgetstr,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: fgetstr,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/fgetstr,v $ ## ## Under source code control: 1996/04/30 03:05:17 diff --git a/help/files b/help/files index 00100bd..4346af3 100644 --- a/help/files +++ b/help/files @@ -29,16 +29,16 @@ DESCRIPTION is assumed to be an open file opened in an unknown mode. Calc will try to read and write to this file when directed. - Consider the following commands: + Consider the following commands shell commands: - $ echo "A line of text in the file on descriptor 5" > datafile - $ calc 5 datafile + calc 5 files(5) + ; files(5) FILE 5 "descriptor[5]" (unknown_mode, pos 0) - > fgetline(files(5)) + ; fgetline(files(5)) "A line of text in the file on descriptor 5" EXAMPLE @@ -68,7 +68,7 @@ SEE ALSO errno, fclose, feof, ferror, fflush, fgetc, fgetline, fgets, files, fopen, fprintf, fputc, fputs, fseek, fsize, ftell, isfile, printf, prompt -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -84,8 +84,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: files,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: files,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/files,v $ ## ## Under source code control: 1995/03/04 11:33:19 diff --git a/help/fputstr b/help/fputstr index de15733..aea866e 100644 --- a/help/fputstr +++ b/help/fputstr @@ -26,7 +26,7 @@ EXAMPLE ; fgetstr(f) "Beta" ; fgetstr(f) - > + ; fputstr(f, "Gamma") Error 72 @@ -39,7 +39,7 @@ LINK LIBRARY SEE ALSO fgetstr, fgetfield, fgets, fputs, fopen, files, fprintf -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -55,8 +55,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: fputstr,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: fputstr,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/fputstr,v $ ## ## Under source code control: 1996/04/30 03:05:18 diff --git a/help/freeredc b/help/freeredc index 86fb2db..4076d56 100644 --- a/help/freeredc +++ b/help/freeredc @@ -19,7 +19,6 @@ EXAMPLE 1 2 15 ; freeredc() ; show redc - > LIMITS none @@ -30,7 +29,7 @@ LINK LIBRARY SEE ALSO free, freeglobals, freestatics -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -46,8 +45,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: freeredc,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: freeredc,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/freeredc,v $ ## ## Under source code control: 1997/09/06 20:03:35 diff --git a/help/indices b/help/indices index 7ec3bce..a62a6a2 100644 --- a/help/indices +++ b/help/indices @@ -26,26 +26,26 @@ DESCRIPTION double-bracket index of the item found. EXAMPLE - > mat M[2,3,1:5] + ; mat M[2,3,1:5] - > indices(M, 11) - list (3 elements, 2 nonzero): - [[0]] = 0 - [[1]] = 2 - [[2]] = 2 + ; indices(M, 11) + list (3 elements, 2 nonzero): + [[0]] = 0 + [[1]] = 2 + [[2]] = 2 - > A = assoc(); + ; A = assoc(); - > A["cat", "dog"] = "fight"; - > A[2,3,5,7] = "primes"; - > A["square", 3] = 9 + ; A["cat", "dog"] = "fight"; + ; A[2,3,5,7] = "primes"; + ; A["square", 3] = 9 - > indices(A, search(A, "primes")) - list (4 elements, 4 nonzero): - [[0]] = 2 - [[1]] = 3 - [[2]] = 5 - [[3]] = 7 + ; indices(A, search(A, "primes")) + list (4 elements, 4 nonzero): + [[0]] = 2 + [[1]] = 3 + [[2]] = 5 + [[3]] = 7 LIMITS abs(index) < 2^31 @@ -57,7 +57,7 @@ LINK LIBRARY SEE ALSO assoc, mat -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -73,8 +73,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.2 $ -## @(#) $Id: indices,v 29.2 2000/06/07 14:02:33 chongo Exp $ +## @(#) $Revision: 29.3 $ +## @(#) $Id: indices,v 29.3 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/indices,v $ ## ## Under source code control: 1999/11/16 08:02:03 diff --git a/help/interrupt b/help/interrupt index 6457567..339b35b 100644 --- a/help/interrupt +++ b/help/interrupt @@ -42,8 +42,8 @@ ABORT opcodes the calculation is never completed and to stop it, an interruption (on many systems, by ctrl-C) will be necessary. - > config("trace", 8), - > define f(x) {local s; while (x) {s += x--} return s} + ; config("trace", 8), + ; define f(x) {local s; while (x) {s += x--} return s} 0: DEBUG line 2 2: PARAMADDR x 4: JUMPZ 19 @@ -68,7 +68,7 @@ ABORT opcodes {s += x--} loop. In interactive mode, with ^C indicating input of ctrl-C, the displayed output is as in: - > f(-1) + ; f(-1) ^C [Abort level 1] "f": line 2: Calculation aborted at statement boundary @@ -77,7 +77,7 @@ ABORT opcodes Changing config("trace") to achieve this, and defining g(x) with the same definition as for f(x) gives: - > define g(x) {local s; while (x) {s += x--} return s} + ; define g(x) {local s; while (x) {s += x--} return s} 0: PARAMADDR x 2: JUMPZ 15 4: LOCALADDR s @@ -94,13 +94,15 @@ ABORT opcodes If g(-1) is called, two interrupts are necessary, as in: - > g(-1) + ; g(-1) ^C [Abort level 1] ^C [Abort level 2] "g": Calculation aborted in opcode +## Copyright (C) 1999-2006 David I. Bell, Landon Curt Noll and 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. @@ -115,8 +117,8 @@ ABORT opcodes ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: interrupt,v 29.4 2000/07/17 15:38:52 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: interrupt,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/interrupt,v $ ## ## Under source code control: 1991/07/21 04:37:21 diff --git a/help/isptr b/help/isptr index 47ba1c8..af50f8a 100644 --- a/help/isptr +++ b/help/isptr @@ -23,13 +23,13 @@ DESCRIPTION strings and real numbers. EXAMPLE - > a = "abc", b = 3, B = blk() - > p1 = &B[1] - > p2 = &a - > p3 = &*a - > p4 = &*b - > print isptr(a), isptr(p1), isptr(p2), isptr(p3), isptr(p4) - 0 1 2 3 4 + ; a = "abc", b = 3, B = blk() + ; p1 = &B[1] + ; p2 = &a + ; p3 = &*a + ; p4 = &*b + ; print isptr(a), isptr(p1), isptr(p2), isptr(p3), isptr(p4) + 0 1 2 3 4 LIMITS none @@ -40,7 +40,7 @@ LINK LIBRARY SEE ALSO isnum, isstr, isblk, isoctet -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -56,8 +56,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.2 $ -## @(#) $Id: isptr,v 29.2 2000/06/07 14:02:33 chongo Exp $ +## @(#) $Revision: 29.3 $ +## @(#) $Id: isptr,v 29.3 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/isptr,v $ ## ## Under source code control: 1997/09/06 20:03:35 diff --git a/help/issq b/help/issq index 1f7383b..16a97e6 100644 --- a/help/issq +++ b/help/issq @@ -16,6 +16,15 @@ DESCRIPTION return 1, otherwise return 0. + Note that issq() works on rational values, so: + + issq(25/16) == 1 + + If you want to test for prefect square integers, you need to exclude + non-integer values before you test: + + isint(curds) && issq(curds) + EXAMPLE ; print issq(25), issq(3), issq(0) 1 0 1 @@ -52,8 +61,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: issq,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: issq,v 29.4 2006/06/04 21:12:23 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/issq,v $ ## ## Under source code control: 1994/10/21 02:21:31 diff --git a/help/mat b/help/mat index ac1e255..d506249 100644 --- a/help/mat +++ b/help/mat @@ -79,10 +79,10 @@ DESCRIPTION simple assignments, as in A[0,0] = 1, A[0,2] = 2; If the index-range is left blank but an initializer list is specified - as in + as in: - mat A[] = {1, 2 } - B = mat[] = {1, , 3, } + ; mat A[] = {1, 2 } + ; B = mat[] = {1, , 3, } the matrix created is one-dimensional. If the list contains a positive number n of values or blanks, the result is as if the @@ -92,11 +92,13 @@ DESCRIPTION B[2] = 3. The specification mat[] = { } creates the same as mat[1]. If the index-range is left blank and no initializer list is specified, - as in mat C[] or C = mat[], the matrix assigned to C has zero - dimension; this has one element C[]. To assign a value using "= { ...}" - at the same time as creating C, parentheses are required as in - (mat[]) = {value} or (mat C[]) = {value}. Later a value may be - assigned to C[] by C[] = value or C = {value}. + as in mat C[] or C = mat[], the matrix assigned to C has zero + dimension; this has one element C[]. + + To assign a value using "= { ...}" at the same time as creating C, + parentheses are required as in (mat[]) = {value} or (mat C[]) = + {value}. Later a value may be assigned to C[] by C[] = value or + C = {value}. The value assigned at any time to any element of a matrix can be of any type - number, string, list, matrix, object of previously specified @@ -106,10 +108,11 @@ DESCRIPTION If an element of a matrix is a structure for which indices or an object element specifier is required, an element of that structure is referred to by appropriate uses of [ ] or ., and so on if an element - of that element is required. For example, one may have an expressions - like + of that element is required. - A[1,2][3].alpha[2]; + For example, one may have an expressions like: + + ; A[1,2][3].alpha[2]; if A[1,2][3].alpha is a list with at least three elements, A[1,2][3] is an object of a type like obj {alpha, beta}, A[1,2] is a matrix of @@ -165,7 +168,7 @@ DESCRIPTION So that when one defines a 2D matrix such as: - mat X[2,3] = {1,2,3,4,5,6} + ; mat X[2,3] = {1,2,3,4,5,6} then printing X results in: @@ -174,20 +177,20 @@ DESCRIPTION The default printing may be restored by - undefine mat_print; + ; undefine mat_print; The keyword "mat" followed by two or more index-range-lists returns a matrix with indices specified by the first list, whose elements are matrices as determined by the later index-range-lists. For example mat[2][3] is a 2-element matrix, each of whose elements has as its value a 3-element matrix. Values may be assigned to the - elements of the innermost matrices by nested = {...} operations as in + elements of the innermost matrices by nested = {...} operations as in - mat [2][3] = {{1,2,3},{4,5,6}} + ; mat [2][3] = {{1,2,3},{4,5,6}} An example of the use of mat with a declarator is - global mat A B [2,3], C [4] + ; global mat A B [2,3], C [4] This creates, if they do not already exist, three global variables with names A, B, C, and assigns to A and B the value mat[2,3] and to C mat[4]. @@ -284,21 +287,21 @@ DESCRIPTION when it is a divisor), int an integer, rnd a rounding-type specifier integer, real a real number. - num * A - A * num - A / num - - A - conj(A) - A << int, A >> int - scale(A, int) - round(A, int, rnd) - bround(A, int, rnd) - appr(A, real, rnd) - int(A) - frac(A) - A // real - A % real - A ^ int + num * A + A * num + A / num + - A + conj(A) + A << int, A >> int + scale(A, int) + round(A, int, rnd) + bround(A, int, rnd) + appr(A, real, rnd) + int(A) + frac(A) + A // real + A % real + A ^ int If A and B are one-dimensional of the same size dp(A, B) returns their dot-product, i.e. the sum of the products of corresponding @@ -344,56 +347,56 @@ DESCRIPTION in effect they are treated as linear arrays. EXAMPLE - > obj point {x,y} - > mat A[5] = {1, 2+3i, "ab", mat[2] = {4,5}, obj point = {6,7}} - > A - mat [5] (5 elements, 5 nonzero): - [0] = 1 - [1] = 2+3i - [2] = "ab" - [3] = mat [2] (2 elements, 2 nonzero) - [4] = obj point {6, 7} + ; obj point {x,y} + ; mat A[5] = {1, 2+3i, "ab", mat[2] = {4,5}, obj point = {6,7}} + ; A + mat [5] (5 elements, 5 nonzero): + [0] = 1 + [1] = 2+3i + [2] = "ab" + [3] = mat [2] (2 elements, 2 nonzero) + [4] = obj point {6, 7} - > print A[0], A[1], A[2], A[3][0], A[4].x - 1 2+3i ab 4 6 + ; print A[0], A[1], A[2], A[3][0], A[4].x + 1 2+3i ab 4 6 - > define point_add(a,b) = obj point = {a.x + b.x, a.y + b.y} - point_add(a,b) defined + ; define point_add(a,b) = obj point = {a.x + b.x, a.y + b.y} + point_add(a,b) defined - > mat [B] = {8, , "cd", mat[2] = {9,10}, obj point = {11,12}} - > A + B + ; mat [B] = {8, , "cd", mat[2] = {9,10}, obj point = {11,12}} + ; A + B - mat [5] (5 elements, 5 nonzero): - [0] = 9 - [1] = 2+3i - [2] = "abcd" - [3] = mat [2] (2 elements, 2 nonzero) - [4] = obj point {17, 19} + mat [5] (5 elements, 5 nonzero): + [0] = 9 + [1] = 2+3i + [2] = "abcd" + [3] = mat [2] (2 elements, 2 nonzero) + [4] = obj point {17, 19} - > mat C[2,2] = {1,2,3,4} - > C^10 + ; mat C[2,2] = {1,2,3,4} + ; C^10 - mat [2,2] (4 elements, 4 nonzero): - [0,0] = 4783807 - [0,1] = 6972050 - [1,0] = 10458075 - [1,1] = 15241882 + mat [2,2] (4 elements, 4 nonzero): + [0,0] = 4783807 + [0,1] = 6972050 + [1,0] = 10458075 + [1,1] = 15241882 - > C^-10 + ; C^-10 - mat [2,2] (4 elements, 4 nonzero): - [0,0] = 14884.650390625 - [0,1] = -6808.642578125 - [1,0] = -10212.9638671875 - [1,1] = 4671.6865234375 + mat [2,2] (4 elements, 4 nonzero): + [0,0] = 14884.650390625 + [0,1] = -6808.642578125 + [1,0] = -10212.9638671875 + [1,1] = 4671.6865234375 - > mat A[4] = {1,2,3,4}, A * reverse(A); + ; mat A[4] = {1,2,3,4}, A * reverse(A); - mat [4] (4 elements, 4 nonzero): - [0] = 4 - [1] = 6 - [2] = 6 - [3] = 4 + mat [4] (4 elements, 4 nonzero): + [0] = 4 + [1] = 6 + [2] = 6 + [3] = 4 LIMITS The theoretical upper bound for the absolute values of indices is @@ -411,7 +414,7 @@ SEE ALSO isident, test, config, search, rsearch, reverse, copy, blkcpy, dp, cp, randperm, sort -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -427,8 +430,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: mat,v 29.4 2005/10/18 10:08:45 chongo Exp $ +## @(#) $Revision: 29.6 $ +## @(#) $Id: mat,v 29.6 2006/06/11 07:25:14 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/mat,v $ ## ## Under source code control: 1991/07/21 04:37:22 diff --git a/help/newerror b/help/newerror index f602fcb..2e57f0d 100644 --- a/help/newerror +++ b/help/newerror @@ -44,12 +44,12 @@ EXAMPLE "triangle side length <= 0" ; define area(a,b,c) { - >> local s; - >> if (!(a > 0) || !(b > 0) || !(c > 0)) return e1; - >> s = (a + b + c)/2; - >> if (s <= a || s <= b || s <= c) return newerror("Non-triangle sides"); - >> return sqrt(s * (s - a) * (s - b) * (s - c)); - >> } + ;; local s; + ;; if (!(a > 0) || !(b > 0) || !(c > 0)) return e1; + ;; s = (a + b + c)/2; + ;; if (s <= a || s <= b || s <= c) return newerror("Non-triangle sides"); + ;; return sqrt(s * (s - a) * (s - b) * (s - c)); + ;; } "area" defined ; A = area(8,2,5); @@ -86,8 +86,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: newerror,v 29.4 2006/05/21 07:31:46 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: newerror,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/newerror,v $ ## ## Under source code control: 1996/04/30 03:39:56 diff --git a/help/param b/help/param index cce8214..ece68bf 100644 --- a/help/param +++ b/help/param @@ -32,11 +32,11 @@ DESCRIPTION EXAMPLE ; define f() { - >> local n, v = 0; - >> for (n = 1; n <= param(0); n++) - >> v += param(n)^2; - >> return v; - >> } + ;; local n, v = 0; + ;; for (n = 1; n <= param(0); n++) + ;; v += param(n)^2; + ;; return v; + ;; } ; print f(), f(1), f(1,2), f(1,2,3) 0 1 5 14 @@ -50,7 +50,7 @@ LINK LIBRARY SEE ALSO argv, command -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -66,8 +66,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: param,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: param,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/param,v $ ## ## Under source code control: 1996/03/12 23:10:01 diff --git a/help/prompt b/help/prompt index 8bdc138..7bbb8c9 100644 --- a/help/prompt +++ b/help/prompt @@ -27,7 +27,6 @@ EXAMPLE ? 2 + 3 25 ? end - > LIMITS none @@ -38,7 +37,7 @@ LINK LIBRARY SEE ALSO XXX - fill in -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -54,8 +53,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: prompt,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: prompt,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/prompt,v $ ## ## Under source code control: 1995/12/18 12:34:58 diff --git a/help/protect b/help/protect index 12382b2..dbdfe6c 100644 --- a/help/protect +++ b/help/protect @@ -20,16 +20,16 @@ DESCRIPTION Each nonzero bit of the low eight bits of sts corresponds to a builtin kind of protection as follows: - bit value protection + bit value protection - 1 no assign to A - 2 no change of A by assignment - 4 no change of type value of A - 8 no error value for A - 16 no copy to A - 32 no relocation for A or its elements - 64 no assign from A - 128 no copy from A + 1 no assign to A + 2 no change of A by assignment + 4 no change of type value of A + 8 no error value for A + 16 no copy to A + 32 no relocation for A or its elements + 64 no assign from A + 128 no copy from A For example, A having protection status 65 = 1 + 64 prevents execution of assignments of the forms A = expression and V = A @@ -55,10 +55,10 @@ DESCRIPTION For the purposes of this function, the depth of a global or local variable is zero; if A has depth d and the value of A is a list, matrix, object or association, its elements have depth d + 1. - For example, after + For example, after: - obj point {x,y} - X = mat[3] = {1, list(2,3), mat[2] = {obj point, obj point} } + ; obj point {x,y} + ; X = mat[3] = {1, list(2,3), mat[2] = {obj point, obj point} } X has depth 0; X[0], X[1] and X[2] have depth 1; X[1][0], X[1][1], X[2][0] and X[2][1] have depth 2; X[2][0].x, X[2][0].y, X[2][1].x @@ -85,14 +85,14 @@ DESCRIPTION Users may define functions that return values with positive status, e.g. - define noassigntovalue(x) {protect(x,1); return x}; - S = noassigntovalue(42); + ; define noassigntovalue(x) {protect(x,1); return x}; + ; S = noassigntovalue(42); will result in S having the value 42 and no-assign-to protection. By using a backquote with a variable as argument, an even simpler function: - define noassignto(x) = protect(x, 1); + ; define noassignto(x) = protect(x, 1); gives no-assign-to protection to the variable; i.e. noassignto(`A) achieves the same as protect(A,1). @@ -128,9 +128,9 @@ DESCRIPTION prevent any change in the content or size of the list. No-relocation protection of a block prevents reallocation of the memory used by a block and the freeing of a named block, For example, - if a block B has maxsize 256, then after + if a block B has maxsize 256, then after: - protect(B, 32); + ; protect(B, 32); copy(A, B) will fail if the copying would cause size(B) to equal or exceed 256; if B is a named block, blkfree(B) will not be permitted. @@ -175,9 +175,10 @@ DESCRIPTION to have positive value. Then code for evaluating a function might include lines like - if (protect(A) & 1024 && B <= 0) - return newerror("Prohibited assignment"); - A = B; + ; if (protect(A) & 1024 && B <= 0) { + ;; return newerror("Prohibited assignment"); + ;; } + ; A = B; When an operation forbidden by a particular bit in the protection status of A is attempted, an error value is created but unless this @@ -200,75 +201,76 @@ DESCRIPTION EXAMPLE - > A = 27 - > protect(A,1) - > A = 45 - > A - 27 - > strerror() - "No-assign-to destination for assign" - > protect(A,64) - > protect(A) - 65 - > X = A - > X - 0 - > strerror() - "No-assign-from source for assign" - > protect(A,-1) - > protect(A) - 64 - > protect(A,4) - > protect(A) - 68 - > A = "abc" - > A - 27 - > strerror() - "No-type-change destination for assign" - > B = 45 - > swap(A,B) - Error 10372 - > strerror() - "No-assign-to-or-from argument for swap" - > protect(A,-64) - > protect(A) - 4 - > swap(A,B) - > A - 45 - > B - 27 + ; A = 27 + ; protect(A,1) + ; A = 45 + ; A + 27 + ; strerror() + "No-assign-to destination for assign" + ; protect(A,64) + ; protect(A) + 65 + ; X = A + ; X + 0 + ; strerror() + "No-assign-from source for assign" + ; protect(A,-1) + ; protect(A) + 64 + ; protect(A,4) + ; protect(A) + 68 + ; A = "abc" + ; A + 27 + ; strerror() + "No-type-change destination for assign" + ; B = 45 + ; swap(A,B) + Error 10372 + ; strerror() + "No-assign-to-or-from argument for swap" + ; protect(A,-64) + ; protect(A) + 4 + ; swap(A,B) + ; A + 45 + ; B + 27 - > A = mat[4] = {1,2,3,4} - > B = list(5,6,7,8) - > protect(A,16) - > copy(B,A) - Error 10226 - > strerror() - "No-copy-to destination variable" + ; A = mat[4] = {1,2,3,4} + ; B = list(5,6,7,8) + ; protect(A,16) + ; copy(B,A) + Error 10226 + ; strerror() + "No-copy-to destination variable" - > A = list(1,2,3) - > protect(A,32) - < append(A,4) - Error 10402 - > strerror() - "No-relocate for list append" + ; A = list(1,2,3) + ; protect(A,32) + ; append(A,4) + Error 10402 + ; strerror() + "No-relocate for list append" - > A = blk(0,5) - > copy("abc", A) - > copy("de",A) - Error 10229 - > strerror() - "No-relocate destination variable" + ; A = blk(0,5) + ; copy("abc", A) + ; copy("de",A) + Error 10229 + ; strerror() + "No-relocate destination variable" + + ; A = blk("alpha") = {1,2,3,4,5} + ; protect(A,0) + ; protect(*A, 16) + ; copy("abc", A) + Error 10228 + ; strerror() + "No-copy-to destination named block" - > A = blk("alpha") = {1,2,3,4,5} - > protect(A,0) - < protect(*A, 16) - < copy("abc", A) - Error 10228 - > strerror() - "No-copy-to destination named block" LIMITS none @@ -278,7 +280,7 @@ LINK LIBRARY SEE ALSO assign, copy, blk, error, errno, strerror -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -294,8 +296,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.4 $ -## @(#) $Id: protect,v 29.4 2006/05/19 15:12:57 chongo Exp $ +## @(#) $Revision: 29.5 $ +## @(#) $Id: protect,v 29.5 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/protect,v $ ## ## Under source code control: 1997/07/10 22:38:44 diff --git a/help/runtime b/help/runtime index 230c737..9a44033 100644 --- a/help/runtime +++ b/help/runtime @@ -28,9 +28,9 @@ LINK LIBRARY none SEE ALSO - ctime + ctime, time -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -46,8 +46,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: runtime,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: runtime,v 29.4 2006/06/04 18:24:33 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/runtime,v $ ## ## Under source code control: 1996/03/12 23:10:01 diff --git a/help/sleep b/help/sleep index ad1806d..2436a7c 100644 --- a/help/sleep +++ b/help/sleep @@ -18,19 +18,18 @@ DESCRIPTION One kind of use is to slow down output to permit easier reading of results, as in: - > for (i = 0; i < 100; i++) { - print sqrt(i); - sleep(1/2); - } + ; for (i = 0; i < 100; i++) { + ;; print sqrt(i); + ;; sleep(1/2); + ;; } The following illustrates what happens if ctrl-C is hit 5 seconds after the first command: - > print sleep(20) + ; print sleep(20) [Abort level 1] 15 - > EXAMPLE ; sleep(1/3); @@ -42,7 +41,7 @@ LIBRARY SEE ALSO none -## Copyright (C) 2000 Ernest Bowen +## Copyright (C) 2000-2006 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 @@ -58,8 +57,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.3 $ -## @(#) $Id: sleep,v 29.3 2006/05/07 07:25:46 chongo Exp $ +## @(#) $Revision: 29.4 $ +## @(#) $Id: sleep,v 29.4 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/sleep,v $ ## ## Under source code control: 2000/12/14 01:33:00 diff --git a/help/test b/help/test index 114504d..f2ec787 100644 --- a/help/test +++ b/help/test @@ -35,15 +35,15 @@ DESCRIPTION Error-value or other types: never EXAMPLE - > print test(27), test(0), test("abc"), test("") - 1 0 1 0 + ; print test(27), test(0), test("abc"), test("") + 1 0 1 0 - > print test(mat[3] = {1,,2}), test(mat[2][2]) - 1 0 + ; print test(mat[3] = {1,,2}), test(mat[2][2]) + 1 0 - > A = list(0, 2, 0) - > print test(A), test(pop(A)), test(A), test(pop(A)), test(A) - 1 0 1 1 0 + ; A = list(0, 2, 0) + ; print test(A), test(pop(A)), test(A), test(pop(A)), test(A) + 1 0 1 1 0 LIMITS none @@ -55,7 +55,7 @@ SEE ALSO isassoc, isfile, isident, isnum, isint, islist, ismat, isnull, isobj, isreal, isstr, issimple, istype -## Copyright (C) 1999 Landon Curt Noll +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -71,8 +71,8 @@ SEE ALSO ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.2 $ -## @(#) $Id: test,v 29.2 2000/06/07 14:02:33 chongo Exp $ +## @(#) $Revision: 29.3 $ +## @(#) $Id: test,v 29.3 2006/06/10 12:28:10 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/test,v $ ## ## Under source code control: 1996/07/11 01:05:13 diff --git a/help/variable b/help/variable index a6c1eab..03a79d0 100644 --- a/help/variable +++ b/help/variable @@ -64,24 +64,83 @@ Variable declarations static mat table[3] = {5, 6, 7}; local obj point p1, p2; - There are no pointers in the calculator language, thus all - arguments to user-defined functions are normally passed by value. - This is true even for matrices, strings, and lists. In order - to circumvent this, the '&' operator is allowed before a variable - when it is an argument to a function. When this is done, the - address of the variable is passed to the function instead of its - value. This is true no matter what the type of the variable is. - This allows for fast calls of functions when the passed variable - is huge (such as a large array). However, the passed variable can - then be changed by the function if the parameter is assigned into. - The function being called does not need to know if the variable - is being passed by value or by address. + When working with user-defined functions, the syntax for passing an + lvalue by reference rather than by value is to precede an expression + for the lvalue by a backquote. For example, if the function invert is + defined by: - Built-in functions and object functions always accept their - arguments as addresses, thus there is no need to use '&' when - calling built-in functions. + define invert(x) {x = inverse(x)} -## Copyright (C) 1999 Landon Curt Noll + then invert(`A) achieves the effect of A = inverse(A). In other + words, passing and argument of `variable (with a back-quote) + will cause and changes to the function argument to be applied to + the calling variable. Calling invert(A) (without the ` backquote) + assigns inverse(A) to the temporary function parameter x and leaves + A unchanged. + + In an argument, a backquote before other than an lvalue is ignored. + Consider, for example: + + ; define logplus(x,y,z) {return log(++x + ++y + ++z);} + + ; eh = 55; + ; mi = 25; + ; answer = logplus(eh, `mi, `17); + + ; print eh, mi, answer; + 55 26 2 + + The value of eh is was not changed because eh was used as + an argument without a back-quote (`). However, mi was incremented + because it was passed as `mi (with a back-quote). Passing 17 + (not an lvalue) as `17 has not effect on the value 17. + + The back-quote should only be used before arguments to a function. + In all other contexts, a backquote causes a compile error. + + Another method is to pass the address of the lvalue explicitly and + use the indirection operator * (star) to refer to the lvalue in the + function body. Consider the following function: + + ; define ten(a) { *a = 10; } + + ; n = 17; + ; ten(n); + ; print n; + 17 + + ; ten(`n); + ; print n; + 17 + + ; ten(&n); + ; print n; + 10 + + Passing an argument with a & (ampersand) allows the tenmore() + function to modify the calling variable: + + ; wa = tenmore(&vx); + ; print vx, wa; + 65 65 + + Great care should be taken when using a pointer to a local variable + or element of a matrix, list or object, since the lvalue pointed to + is deleted when evaluation of the function is completed or the lvalue + whose value is the matrix, list or object is assigned another value. + + As both of the above methods (using & arguments (ampersand) *value + (star) function values or by using ` arguments (back quote) alone) + copy the address rather than the value of the argument to the function + parameter, they allow for faster calls of functions when the memory + required for the value is huge (such as for a large matrix). + + As the built-in functions and object functions always accept their + arguments as addresses, there is no gain in using the backquote when + calling these functions. + + +## Copyright (C) 1999-2006 Landon Curt Noll ## ## 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 @@ -97,8 +156,8 @@ Variable declarations ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## -## @(#) $Revision: 29.2 $ -## @(#) $Id: variable,v 29.2 2000/06/07 14:02:33 chongo Exp $ +## @(#) $Revision: 29.3 $ +## @(#) $Id: variable,v 29.3 2006/06/11 07:50:48 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/variable,v $ ## ## Under source code control: 1991/07/21 04:37:25 diff --git a/quickhash.c b/quickhash.c index 6342004..acf73c9 100644 --- a/quickhash.c +++ b/quickhash.c @@ -17,8 +17,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.9 $ - * @(#) $Id: quickhash.c,v 29.9 2006/05/20 08:43:55 chongo Exp $ + * @(#) $Revision: 29.10 $ + * @(#) $Id: quickhash.c,v 29.10 2006/06/06 07:17:02 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/quickhash.c,v $ * * Under source code control: 1995/03/04 11:34:23 @@ -487,6 +487,7 @@ config_hash(CONFIG *cfg, QCKHASH val) if (cfg->version) { val = fnv_strhash(cfg->version, val); } + value = (((value>>5) | (value<<27)) ^ (USB32)cfg->baseb); /* * hash the epsilon if possible diff --git a/version.c b/version.c index 9899748..8abb41a 100644 --- a/version.c +++ b/version.c @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.59 $ - * @(#) $Id: version.c,v 29.59 2006/06/03 22:52:39 chongo Exp $ + * @(#) $Revision: 29.60 $ + * @(#) $Id: version.c,v 29.60 2006/06/11 07:52:58 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/version.c,v $ * * Under source code control: 1990/05/22 11:00:58 @@ -48,7 +48,7 @@ static char *program; #define MAJOR_VER 2 /* major version */ #define MINOR_VER 12 /* minor version */ #define MAJOR_PATCH 0 /* patch level or 0 if no patch */ -#define MINOR_PATCH 2 /* test number or 0 if no minor patch */ +#define MINOR_PATCH 3 /* test number or 0 if no minor patch */ /* diff --git a/zfunc.c b/zfunc.c index 35efb01..a606c4f 100644 --- a/zfunc.c +++ b/zfunc.c @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.7 $ - * @(#) $Id: zfunc.c,v 29.7 2006/05/20 08:43:55 chongo Exp $ + * @(#) $Revision: 29.8 $ + * @(#) $Id: zfunc.c,v 29.8 2006/06/04 20:18:44 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/zfunc.c,v $ * * Under source code control: 1990/02/15 01:48:27 @@ -37,6 +37,148 @@ ZVALUE _tenpowers_[TEN_MAX+1]; /* table of 10^2^n */ static long *power10 = NULL; static int max_power10_exp = 0; +/* + * given: + * + * unsigned long x + * or: unsigned long long x + * or: long x and x >= 0 + * or: long long x and x >= 0 + * + * If issq_mod4k[x & 0xfff] == 0, then x cannot be a perfect square + * else x might be a perfect square. + */ +static USB8 issq_mod4k[1<<12] = { + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, + 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +}; + /* * Compute the factorial of a number. @@ -1945,7 +2087,7 @@ zroot(ZVALUE z1, ZVALUE z2, ZVALUE *dest) BOOL zissquare(ZVALUE z) { - long n, i; + long n; ZVALUE tmp; /* negative values are never perfect squares */ @@ -1964,17 +2106,10 @@ zissquare(ZVALUE z) return TRUE; } - /* check mod 16 values */ - n = (long)(*z.v & 0xf); - if ((n != 0) && (n != 1) && (n != 4) && (n != 9)) + /* check mod 4096 values */ + if (issq_mod4k[(int)(*z.v & 0xfff)] == 0) { return FALSE; - - /* check mod 256 values */ - n = (long)(*z.v & 0xff); - i = 0x80; - while (((i * i) & 0xff) != n) - if (--i <= 0) - return FALSE; + } /* must do full square root test now */ n = !zsqrt(z, &tmp, 0); diff --git a/zmath.h b/zmath.h index d79c575..621c0a9 100644 --- a/zmath.h +++ b/zmath.h @@ -17,8 +17,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.15 $ - * @(#) $Id: zmath.h,v 29.15 2006/05/21 07:10:22 chongo Exp $ + * @(#) $Revision: 29.17 $ + * @(#) $Id: zmath.h,v 29.17 2006/06/11 07:07:23 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/zmath.h,v $ * * Under source code control: 1993/07/30 19:42:48 @@ -228,11 +228,12 @@ typedef SB32 LEN; /* unit of length storage */ #define MAXLEN ((LEN) 0x7fffffff >> 3) /* longest value allowed */ -#define MAXREDC 5 /* number of entries in REDC cache */ -#define SQ_ALG2 20 /* size for alternative squaring */ -#define MUL_ALG2 20 /* size for alternative multiply */ -#define POW_ALG2 40 /* size for using REDC for powers */ -#define REDC_ALG2 50 /* size for using alternative REDC */ +#define MAXREDC 64 /* number of entries in REDC cache */ +#define SQ_ALG2 3388 /* size for alternative squaring */ +#define MUL_ALG2 1780 /* size for alternative multiply */ +#define POW_ALG2 176 /* size for using REDC for powers */ +/* old REDC_ALG2 was 5/4 of POW_ALG2, so we will keep the same ratio */ +#define REDC_ALG2 220 /* size for using alternative REDC */ typedef union { diff --git a/zmod.c b/zmod.c index c5640c8..97d7780 100644 --- a/zmod.c +++ b/zmod.c @@ -19,8 +19,8 @@ * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * - * @(#) $Revision: 29.3 $ - * @(#) $Id: zmod.c,v 29.3 2000/07/17 15:35:49 chongo Exp $ + * @(#) $Revision: 29.4 $ + * @(#) $Id: zmod.c,v 29.4 2006/06/11 00:08:56 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/zmod.c,v $ * * Under source code control: 1991/05/22 23:03:55 @@ -1197,7 +1197,7 @@ zredcmul(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res) ZVALUE z1tmp, z2tmp; int sign; - sign = z1.sign ^ z2.sign;; + sign = z1.sign ^ z2.sign; z1.sign = 0; z2.sign = 0; z1tmp.len = 0;