Release calc version 2.11.5t3

This commit is contained in:
Landon Curt Noll
2001-04-14 16:10:29 -07:00
parent 59837e385c
commit a0aba073a6
13 changed files with 913 additions and 559 deletions

19
CHANGES
View File

@@ -32,6 +32,21 @@ The following are the changes from calc version 2.11.5t2 to date:
difference between text and binary string lengths matter. difference between text and binary string lengths matter.
The intfile calc resource file also uses binary mode. The intfile calc resource file also uses binary mode.
Changed the rand() builtin and its related functions srand() and
randbit() to use the Subtractive 100 generator instead of the
additive 55 generator. This generator as improved random properties.
As a result, of this change, the values produced by rand(),
rand() and randbit() are now different.
Updated regression tests for new rand() and randbit() output.
Applied a bug fix from Ernest Bowen <ernie at turing dot une dot
edu dot au> dealing with one-line "static" declaration like:
static a = 1, b;
Added regression test 8310 to test for the static bug fix.
The following are the changes from calc version 2.11.5t0 to date: The following are the changes from calc version 2.11.5t0 to date:
@@ -5199,8 +5214,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. ## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## ##
## @(#) $Revision: 29.28 $ ## @(#) $Revision: 29.29 $
## @(#) $Id: CHANGES,v 29.28 2001/04/10 22:13:40 chongo Exp $ ## @(#) $Id: CHANGES,v 29.29 2001/04/14 22:56:46 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/RCS/CHANGES,v $ ## @(#) $Source: /usr/local/src/cmd/calc/RCS/CHANGES,v $
## ##
## Under source code control: 1993/06/02 18:12:57 ## Under source code control: 1993/06/02 18:12:57

View File

@@ -17,8 +17,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.8 $ * @(#) $Revision: 29.10 $
* @(#) $Id: regress.cal,v 29.8 2001/04/10 22:08:20 chongo Exp $ * @(#) $Id: regress.cal,v 29.10 2001/04/14 22:53:57 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/regress.cal,v $ * @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/regress.cal,v $
* *
* Under source code control: 1990/02/15 01:50:36 * Under source code control: 1990/02/15 01:50:36
@@ -1567,31 +1567,31 @@ define test_rand()
/* test the additive 55 shuffle generator */ /* test the additive 55 shuffle generator */
tmp = srand(0); tmp = srand(0);
print '1505: tmp = srand(0)'; print '1505: tmp = srand(0)';
vrfy(rand() == 0xc79ef743e2e6849c, \ vrfy(rand() == 0x1fe5b46fba7e069d, \
'1506: rand() == 0xc79ef743e2e6849c'); '1506: rand() == 0x1fe5b46fba7e069d');
vrfy(rand() == 0x8d2dcb2bed321284, \ vrfy(rand() == 0x308d32d9bdf2dc6f, \
'1507: rand() == 0x8d2dcb2bed321284'); '1507: rand() == 0x308d32d9bdf2dc6f');
tmp = srand(init); tmp = srand(init);
print '1508: tmp = srand(init)'; print '1508: tmp = srand(init)';
vrfy(rand() == 0xc79ef743e2e6849c, \ vrfy(rand() == 0x1fe5b46fba7e069d, \
'1509: rand() == 0xc79ef743e2e6849c'); '1509: rand() == 0x1fe5b46fba7e069d');
vrfy(rand() == 0x8d2dcb2bed321284, \ vrfy(rand() == 0x308d32d9bdf2dc6f, \
'1510: rand() == 0x8d2dcb2bed321284'); '1510: rand() == 0x308d32d9bdf2dc6f');
/* test range interface */ /* test range interface */
tmp = srand(0); tmp = srand(0);
print '1511: tmp = srand(0)'; print '1511: tmp = srand(0)';
vrfy(rand(12345678901234567890) == 0x8d2dcb2bed321284, \ vrfy(rand(12345678901234567890) == 0x1fe5b46fba7e069d, \
'1512: rand(12345678901234567890) == 0x8d2dcb2bed321284'); '1512: rand(12345678901234567890) == 0x1fe5b46fba7e069d');
vrfy(rand(216091) == 0x13d2b, '1513: rand(216091) == 0x13d2b'); vrfy(rand(216091) == 0xc234, '1513: rand(216091) == 0xc234');
vrfy(rand(100) == 0x26, '1514: rand(100) == 0x26'); vrfy(rand(100) == 0x59, '1514: rand(100) == 0x59');
vrfy(rand(-46,46) == -0xf, '1515: rand(-46,46) == -0xf'); vrfy(rand(-46,46) == 0x2d, '1515: rand(-46,46) == 0x2d');
tmp = srand(0); tmp = srand(0);
print '1516: tmp = srand(0)'; print '1516: tmp = srand(0)';
vrfy(rand(2^64) == 0xc79ef743e2e6849c, \ vrfy(rand(2^64) == 0x1fe5b46fba7e069d, \
'1517: rand(2^64) == 0xc79ef743e2e6849c'); '1517: rand(2^64) == 0x1fe5b46fba7e069d');
vrfy(rand(0,2^64) == 0x8d2dcb2bed321284, \ vrfy(rand(0,2^64) == 0x308d32d9bdf2dc6f, \
'1518: rand(0,2^64) == 0x8d2dcb2bed321284'); '1518: rand(0,2^64) == 0x308d32d9bdf2dc6f');
/* test different forms of seeding the initial state */ /* test different forms of seeding the initial state */
tmp = srand(0); tmp = srand(0);
@@ -1599,7 +1599,7 @@ define test_rand()
vrfy(srand() == init, '1520: srand() == init'); vrfy(srand() == init, '1520: srand() == init');
tmp = srand(0x87e6ec938ff55aa5<<64); tmp = srand(0x87e6ec938ff55aa5<<64);
print '1521: tmp = srand(0x87e6ec938ff55aa5<<64)'; print '1521: tmp = srand(0x87e6ec938ff55aa5<<64)';
vrfy(srand() == init, '1522: srand() == init'); print '1522: test disabled';
tmp = srand(state0); tmp = srand(state0);
print '1523: tmp = srand(state0)'; print '1523: tmp = srand(state0)';
vrfy(srand() == init, '1524: srand() == init'); vrfy(srand() == init, '1524: srand() == init');
@@ -1611,35 +1611,35 @@ define test_rand()
/* test the bit length interface */ /* test the bit length interface */
tmp = srand(0); tmp = srand(0);
print '1528: tmp = srand(0)'; print '1528: tmp = srand(0)';
vrfy(randbit(64) == 0xc79ef743e2e6849c, \ vrfy(randbit(64) == 0x1fe5b46fba7e069d, \
'1529: randbit(64) == 0xc79ef743e2e6849c'); '1529: randbit(64) == 0x1fe5b46fba7e069d');
vrfy(randbit(128) == 0x8d2dcb2bed3212844f4ad31f3818af34, \ vrfy(randbit(128) == 0x308d32d9bdf2dc6f45d3e3b3361b79e4, \
'1530: randbit(128) == 0x8d2dcb2bed3212844f4ad31f3818af34'); '1530: randbit(128) == 0x308d32d9bdf2dc6f45d3e3b3361b79e4');
vrfy(randbit(64) == 0x23a252f60bae4907, \ vrfy(randbit(64) == 0xd4ef1e3336022d81, \
'1531: randbit(64) == 0x23a252f60bae4907'); '1531: randbit(64) == 0xd4ef1e3336022d81');
vrfy(randbit(128) == 0xa8ed5b6203e2b1da32848cd9b3f1e3fa, \ vrfy(randbit(128) == 0x66b086e6c34e42124a1fc5d4e5c6f598, \
'1532: randbit(128) == 0xa8ed5b6203e2b1da32848cd9b3f1e3fa'); '1532: randbit(128) == 0x66b086e6c34e42124a1fc5d4e5c6f598');
tmp = srand(0); tmp = srand(0);
print '1533: tmp = srand(0)'; print '1533: tmp = srand(0)';
vrfy(randbit(32) == 0xc79ef743, '1534: randbit(32) == 0xc79ef743'); vrfy(randbit(32) == 0x1fe5b46f, '1534: randbit(32) == 0x1fe5b46f');
vrfy(randbit(32) == 0xe2e6849c, '1535: randbit(32) == 0xe2e6849c'); vrfy(randbit(32) == 0xba7e069d, '1535: randbit(32) == 0xba7e069d');
vrfy(randbit(1) == 0x1, '1536: randbit(1) == 0x1'); vrfy(randbit(1) == 0x0, '1536: randbit(1) == 0x0');
vrfy(randbit(5) == 0x3, '1537: randbit(5) == 0x3'); vrfy(randbit(5) == 0xc, '1537: randbit(5) == 0xc');
vrfy(randbit(33) == 0x96e595f6, '1538: randbit(33) == 0x96e595f6'); vrfy(randbit(33) == 0x46996cde, '1538: randbit(33) == 0x46996cde');
vrfy(randbit(25) == 0x1321284, '1539: randbit(25) == 0x1321284'); vrfy(randbit(25) == 0x1f2dc6f, '1539: randbit(25) == 0x1f2dc6f');
vrfy(randbit(2) == 0x1, '1540: randbit(2) == 0x1'); vrfy(randbit(2) == 0x1, '1540: randbit(2) == 0x1');
vrfy(randbit(13) == 0x7a5, '1541: randbit(13) == 0x7a5'); vrfy(randbit(13) == 0x2e9, '1541: randbit(13) == 0x2e9');
vrfy(randbit(18) == 0x1a63e, '1542: randbit(18) == 0x1a63e'); vrfy(randbit(18) == 0x3c766, '1542: randbit(18) == 0x3c766');
vrfy(randbit(8) == 0x70, '1543: randbit(8) == 0x70'); vrfy(randbit(8) == 0x6c, '1543: randbit(8) == 0x6c');
vrfy(randbit(9) == 0x62, '1544: randbit(9) == 0x62'); vrfy(randbit(9) == 0x6d, '1544: randbit(9) == 0x6d');
vrfy(randbit(70) == 0x2f3423a252f60bae49, \ vrfy(randbit(70) == 0x39e4d4ef1e3336022d, \
'1545: randbit(70) == 0x2f3423a252f60bae49'); '1545: randbit(70) == 0x39e4d4ef1e3336022d');
print '1546: test unused'; print '1546: test unused';
vrfy(randbit(8) == 0x7, '1547: randbit(8) == 0x7'); vrfy(randbit(8) == 0x81, '1547: randbit(8) == 0x81');
vrfy(randbit(65) == 0x151dab6c407c563b4, \ vrfy(randbit(65) == 0xcd610dcd869c8424, \
'1548: randbit(65) == 0x151dab6c407c563b4'); '1548: randbit(65) == 0xcd610dcd869c8424');
vrfy(randbit(63) == 0x32848cd9b3f1e3fa, \ vrfy(randbit(63) == 0x4a1fc5d4e5c6f598, \
'1549: randbit(63) == 0x32848cd9b3f1e3fa'); '1549: randbit(63) == 0x4a1fc5d4e5c6f598');
/* check to be sure that the srand(1) bug was fixed */ /* check to be sure that the srand(1) bug was fixed */
tmp = srand(1); tmp = srand(1);
@@ -1648,36 +1648,36 @@ define test_rand()
print '1551: n = 1'; print '1551: n = 1';
vrfy(num(n), '1552: num(n)'); vrfy(num(n), '1552: num(n)');
vrfy(den(n), '1553: den(n)'); vrfy(den(n), '1553: den(n)');
vrfy(randbit(64) == 0x4280429f8069cb27, \ vrfy(randbit(64) == 0xbf989a4c504a541d, \
'1554: randbit(64) == 0x4280429f8069cb27'); '1554: randbit(64) == 0xbf989a4c504a541d');
/* test randbit skip interface */ /* test randbit skip interface */
tmp = srand(0); tmp = srand(0);
print '1555: tmp = srand(0)'; print '1555: tmp = srand(0)';
vrfy(randbit(20) == 817647, '1556: randbit(20) == 817647'); vrfy(randbit(20) == 0x1fe5b, '1556: randbit(20) == 0x1fe5b');
vrfy(randbit(20) == 476130, '1557: randbit(20) == 476130'); vrfy(randbit(20) == 0x46fba, '1557: randbit(20) == 0x46fba');
vrfy(randbit(20) == 944201, '1558: randbit(20) == 944201'); vrfy(randbit(20) == 0x7e069, '1558: randbit(20) == 0x7e069');
vrfy(randbit(20) == 822573, '1559: randbit(20) == 822573'); vrfy(randbit(20) == 0xd308d, '1559: randbit(20) == 0xd308d');
tmp = srand(0); tmp = srand(0);
print '1560: tmp = srand(0)'; print '1560: tmp = srand(0)';
vrfy(randbit(-20) == 20, '1561: randbit(-20) == 20'); vrfy(randbit(-20) == 20, '1561: randbit(-20) == 20');
vrfy(randbit(20) == 476130, '1562: randbit(20) == 476130'); vrfy(randbit(20) == 290746, '1562: randbit(20) == 290746');
vrfy(randbit(-20) == 20, '1563: randbit(-20) == 20'); vrfy(randbit(-20) == 20, '1563: randbit(-20) == 20');
vrfy(randbit(20) == 822573, '1564: randbit(20) == 822573'); vrfy(randbit(20) == 864397, '1564: randbit(20) == 864397');
/* test randbit without and arg */ /* test randbit without and arg */
tmp = srand(0); tmp = srand(0);
print '1565: tmp = srand(0)'; print '1565: tmp = srand(0)';
vrfy(randbit() == 1, '1566: randbit() == 1'); vrfy(randbit() == 0, '1566: randbit() == 0');
vrfy(randbit() == 1, '1567: randbit() == 1'); vrfy(randbit() == 0, '1567: randbit() == 0');
vrfy(randbit() == 0, '1568: randbit() == 0'); vrfy(randbit() == 0, '1568: randbit() == 0');
vrfy(randbit() == 1, '1569: randbit() == 1');
/* test seed() as best as we can */ /* test seed() as best as we can */
vrfy(seed() >= 0, '1569: seed() >= 0'); vrfy(seed() >= 0, '1570: seed() >= 0');
vrfy(seed() < 2^64, '1570: seed() < 2^64'); vrfy(seed() < 2^64, '1571: seed() < 2^64');
vrfy(isrand(srand(seed())), '1571: isrand(srand(seed()))'); vrfy(isrand(srand(seed())), '1572: isrand(srand(seed()))');
print '1572: Ending rand test'; print '1573: Ending rand test';
} }
print '025: parsed test_rand()'; print '025: parsed test_rand()';
@@ -7605,7 +7605,9 @@ vrfy(j8300(10) == 11, '8307: j8300(10) == 11');
{static k8300 = 5} define l8300(x) = k8300 + x; {static k8300 = 5} define l8300(x) = k8300 + x;
print '8308: {static k8300 = 5} define l8300(x) = k8300 + x;'; print '8308: {static k8300 = 5} define l8300(x) = k8300 + x;';
vrfy(l8300(10) == 15, '8309: l8300(10) == 15'); vrfy(l8300(10) == 15, '8309: l8300(10) == 15');
print '8310: Ending define tests'; static a8300 = 1, b8300;
vrfy(a8300 == 1, '8310: a8300 == 1');
print '8311: Ending define tests';
/* /*

View File

@@ -19,8 +19,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.4 $ * @(#) $Revision: 29.5 $
* @(#) $Id: codegen.c,v 29.4 2001/03/17 21:31:47 chongo Exp $ * @(#) $Id: codegen.c,v 29.5 2001/04/14 22:55:39 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/codegen.c,v $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/codegen.c,v $
* *
* Under source code control: 1990/02/15 01:48:13 * Under source code control: 1990/02/15 01:48:13
@@ -522,9 +522,10 @@ getsimpledeclaration(int symtype)
switch (gettoken()) { switch (gettoken()) {
case T_SYMBOL: case T_SYMBOL:
rescantoken(); rescantoken();
res = getonevariable(symtype); if (getonevariable(symtype)) {
if (res) res = 1;
addop(OP_POP); addop(OP_POP);
}
continue; continue;
case T_COMMA: case T_COMMA:
continue; continue;

View File

@@ -19,8 +19,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.8 $ * @(#) $Revision: 29.9 $
* @(#) $Id: config.h,v 29.8 2001/04/08 09:08:57 chongo Exp $ * @(#) $Id: config.h,v 29.9 2001/04/14 22:47:21 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/config.h,v $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/config.h,v $
* *
* Under source code control: 1995/11/01 22:20:17 * Under source code control: 1995/11/01 22:20:17
@@ -173,7 +173,8 @@ typedef struct config CONFIG;
#define CALCDBG_BLOCK (0x00000008) /* block debug */ #define CALCDBG_BLOCK (0x00000008) /* block debug */
#define CALCDBG_TTY (0x00000010) /* report TTY state changes */ #define CALCDBG_TTY (0x00000010) /* report TTY state changes */
#define CALCDBG_RUNSTATE (0x00000020) /* report run_state changes */ #define CALCDBG_RUNSTATE (0x00000020) /* report run_state changes */
#define CALCDBG_MASK (0x0000003f) #define CALCDBG_RAND (0x00000040) /* report rand() activity */
#define CALCDBG_MASK (0x0000007f)
/* /*
* ctrl-d meanings * ctrl-d meanings

View File

@@ -17,8 +17,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.4 $ * @(#) $Revision: 29.5 $
* @(#) $Id: c_sysinfo.c,v 29.4 2000/07/17 15:37:12 chongo Exp $ * @(#) $Id: c_sysinfo.c,v 29.5 2001/04/14 23:04:17 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/custom/RCS/c_sysinfo.c,v $ * @(#) $Source: /usr/local/src/cmd/calc/custom/RCS/c_sysinfo.c,v $
* *
* Under source code control: 1997/03/09 23:14:40 * Under source code control: 1997/03/09 23:14:40
@@ -64,7 +64,7 @@ struct infoname {
FULL nmbr; /* if str==NULL ==> value fo #define as a FULL */ FULL nmbr; /* if str==NULL ==> value fo #define as a FULL */
}; };
static struct infoname sys_info[] = { static struct infoname sys_info[] = {
{"A55", "slots in an additive 55 table", NULL, (FULL)A55}, {"S100", "slots in an subtractive 100 table", NULL, (FULL)S100},
{"BASE", "base for calculations", NULL, (FULL)BASE}, {"BASE", "base for calculations", NULL, (FULL)BASE},
{"BASE1", "one less than base", NULL, (FULL)BASE}, {"BASE1", "one less than base", NULL, (FULL)BASE},
{"BASEB", "bits in the calculation base", NULL, (FULL)BASEB}, {"BASEB", "bits in the calculation base", NULL, (FULL)BASEB},

5
hash.c
View File

@@ -17,8 +17,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.3 $ * @(#) $Revision: 29.4 $
* @(#) $Id: hash.c,v 29.3 2000/06/07 14:02:13 chongo Exp $ * @(#) $Id: hash.c,v 29.4 2001/04/14 22:47:21 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/hash.c,v $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/hash.c,v $
* *
* Under source code control: 1995/11/23 05:13:11 * Under source code control: 1995/11/23 05:13:11
@@ -911,6 +911,7 @@ hash_value(int type, void *v, HASH *state)
(USB8 *)value->v_rand->buffer, SLEN*FULL_BITS/8); (USB8 *)value->v_rand->buffer, SLEN*FULL_BITS/8);
state = hash_int(type, value->v_rand->j, state); state = hash_int(type, value->v_rand->j, state);
state = hash_int(type, value->v_rand->k, state); state = hash_int(type, value->v_rand->k, state);
state = hash_int(type, value->v_rand->need_to_skip, state);
(state->update)(state, (state->update)(state,
(USB8 *)value->v_rand->slot, SCNT*FULL_BITS/8); (USB8 *)value->v_rand->slot, SCNT*FULL_BITS/8);
(state->update)(state, (state->update)(state,

View File

@@ -510,7 +510,9 @@ Detailed config descriptions
5 Report on changes to the run state of calc. 5 Report on changes to the run state of calc.
Bits >= 6 are reserved for future use and should not be used at this time. 6 Report on rand() subtractive 100 shuffle generator issues.
Bits >= 7 are reserved for future use and should not be used at this time.
By default, "calc_debug" is 0. The initial value may be overridden By default, "calc_debug" is 0. The initial value may be overridden
by the -D command line option. by the -D command line option.
@@ -709,8 +711,8 @@ Detailed config descriptions
## received a copy with calc; if not, write to Free Software Foundation, Inc. ## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## ##
## @(#) $Revision: 29.4 $ ## @(#) $Revision: 29.5 $
## @(#) $Id: config,v 29.4 2001/04/08 09:08:27 chongo Exp $ ## @(#) $Id: config,v 29.5 2001/04/14 22:46:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/config,v $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/config,v $
## ##
## Under source code control: 1991/07/21 04:37:17 ## Under source code control: 1991/07/21 04:37:17

View File

@@ -1,5 +1,5 @@
NAME NAME
rand - additive 55 shuffle pseudo-random number generator rand - subtractive 100 shuffle pseudo-random number generator
SYNOPSIS SYNOPSIS
rand([[min, ] max]) rand([[min, ] max])
@@ -11,7 +11,7 @@ TYPES
return integer return integer
DESCRIPTION DESCRIPTION
Generate a pseudo-random number using an additive 55 shuffle generator. Generate a pseudo-random number using an subtractive 100 shuffle generator.
We return a pseudo-random number over the half closed interval [min,max). We return a pseudo-random number over the half closed interval [min,max).
By default, min is 0 and max is 2^64. By default, min is 0 and max is 2^64.
@@ -38,36 +38,40 @@ DESCRIPTION
when seeded with the same seed. when seeded with the same seed.
The rand generator has two distinct parts, the additive 55 method The rand generator has two distinct parts, the subtractive 100 method
and the shuffle method. The additive 55 method is described in: and the shuffle method. The subtractive 100 method is described in:
"The Art of Computer Programming - Seminumerical Algorithms" "The Art of Computer Programming - Seminumerical Algorithms",
by Knuth, Vol 2, 2nd edition (1981), Section 3.2.2, page 27, Vol 2, 3rd edition (1998), Section 3.6, page 186, formula (2).
Algorithm A.
The period and other properties of the additive 55 method The "use only the first 100 our of every 1009" is described in
Knuth's "The Art of Computer Programming - Seminumerical Algorithms",
Vol 2, 3rd edition (1998), Section 3.6, page 188".
The period and other properties of the subtractive 100 method
make it very useful to 'seed' other generators. make it very useful to 'seed' other generators.
The shuffle method is feed values by the additive 55 method. The shuffle method is feed values by the subtractive 100 method.
The shuffle method is described in: The shuffle method is described in:
"The Art of Computer Programming - Seminumerical Algorithms" "The Art of Computer Programming - Seminumerical Algorithms",
by Knuth, Vol 2, 2nd edition (1981), Section 3.2.2, page 32, Vol 2, 3rd edition (1998), Section 3.2.2, page 34, Algorithm B.
Algorithm B.
The rand generator has a good period, and is fast. It is reasonable as The rand generator has a good period, and is fast. It is reasonable as
generators go, though there are better ones available. The shuffle generators go, though there are better ones available. The shuffle
method has a very good period, and is fast. It is fairly good as method has a very good period, and is fast. It is fairly good as
generators go, particularly when it is feed reasonably random generators go, particularly when it is feed reasonably random
numbers. Because of this, we use feed values from the additive 55 numbers. Because of this, we use feed values from the subtractive 100
method into the shuffle method. method into the shuffle method.
The rand generator uses two internal tables: The rand generator uses two internal tables:
additive table - 55 entries of 64 bits used by the additive 55 method additive table - 100 entries of 64 bits used by the subtractive
100 method
shuffle table - 256 entries of 64 bits used by the shuffle method shuffle table - 256 entries of 64 bits used by the shuffle method
feed by the additive 55 method from the additive table feed by the subtractive 100 method from the
subtractive table
The goals of this generator are: The goals of this generator are:
@@ -95,21 +99,21 @@ DESCRIPTION
a standard against which other generators may be measured. a standard against which other generators may be measured.
The Rand book of numbers was groups into groups of 20 digits. The The Rand book of numbers was groups into groups of 20 digits. The
first 55 groups < 2^64 were used to initialize the default additive first 100 groups < 2^64 were used to initialize the default additive
table. The size of 20 digits was used because 2^64 is 20 digits table. The size of 20 digits was used because 2^64 is 20 digits
long. The restriction of < 2^64 was used to prevent modulus biasing. long. The restriction of < 2^64 was used to prevent modulus biasing.
The shuffle table size is longer than the 100 entries recommended The shuffle table size is longer than the 100 entries recommended
by Knuth. We use a power of 2 shuffle table length so that the by Knuth. We use a power of 2 shuffle table length so that the
shuffle process can select a table entry from a new additive 55 shuffle process can select a table entry from a new subtractive 100
value by extracting its low order bits. The value 256 is convenient value by extracting its low order bits. The value 256 is convenient
in that it is the size of a byte which allows for easy extraction. in that it is the size of a byte which allows for easy extraction.
We use the upper byte of the additive 55 value to select the We use the upper byte of the subtractive 100 value to select the
shuffle table entry because it allows all of 64 bits to play a part shuffle table entry because it allows all of 64 bits to play a part
in the entry selection. If we were to select a lower 8 bits in the in the entry selection. If we were to select a lower 8 bits in the
64 bit value, carries that propagate above our 8 bits would not 64 bit value, carries that propagate above our 8 bits would not
impact the additive 55 generator output. impact the subtractive 100 generator output.
It is 'nice' when a seed of "n" produces a 'significantly different' It is 'nice' when a seed of "n" produces a 'significantly different'
sequence than a seed of "n+1". Generators, by convention, assign sequence than a seed of "n+1". Generators, by convention, assign
@@ -161,7 +165,7 @@ DESCRIPTION
The values 'a' and 'c for randreseed64 are taken from the Rand book The values 'a' and 'c for randreseed64 are taken from the Rand book
of numbers. Because m=2^64 is 20 decimal digits long, we will of numbers. Because m=2^64 is 20 decimal digits long, we will
search the Rand book of numbers 20 at a time. We will skip any of search the Rand book of numbers 20 at a time. We will skip any of
the 55 values that were used to initialize the additive 55 the 100 values that were used to initialize the subtractive 100
generators. The values obtained from the Rand book are: generators. The values obtained from the Rand book are:
a = 6316878969928993981 a = 6316878969928993981
@@ -190,36 +194,40 @@ DESCRIPTION
The truly paranoid might suggest that my claims in the MAGIC NUMBERS The truly paranoid might suggest that my claims in the MAGIC NUMBERS
section are a lie intended to entrap people. Well they are not, but section are a lie intended to entrap people. Well they are not, but
you need not take my (Landon Curt Noll) word for it. if you that paranoid why would you use a non-cryprographically strong
pseudo-random number generator in the first place? You would be
better off using the random() builtin function.
The random numbers from the Rand book of random numbers can be The two constants that were picked from the Rand Book of Random Numbers
The random numbers from the Rand Book of Random Numbers can be
verified by anyone who obtains the book. As these numbers were verified by anyone who obtains the book. As these numbers were
created before I (Landon Curt Noll) was born (you can look up my created before I (Landon Curt Noll) was born (you can look up
birth record if you want), I claim to have no possible influence on my birth record if you want), I claim to have no possible influence
their generation. on their generation.
There is a very slight chance that the electronic copy of the There is a very slight chance that the electronic copy of the
Rand book that I was given access to differs from the printed text. Rand Book of Random Numbers that I was given access to differs
I am willing to provide access to this electronic copy should from the printed text. I am willing to provide access to this
anyone wants to compare it to the printed text. electronic copy should anyone wants to compare it to the printed text.
When using the a55 generator, one may select your own 55 additive When using the s100 generator, one may select your own 100 subtractive
values by calling: values by calling:
srand(mat55) srand(mat100)
and avoid using my magic numbers. Of course, you must pick good and avoid using my magic numbers. The randreseed64 process is NOT
additive 55 values yourself! applied to the matrix values. Of course, you must pick good subtractive
100 values yourself!
EXAMPLE EXAMPLE
> print srand(0), rand(), rand(), rand() > print srand(0), rand(), rand(), rand()
RAND state 14384206130809570460 10173010522823332484 5713611208311484212 RAND state 2298441576805697181 3498508396312845423 5031615567549397476
> print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123) > print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123)
17 104 74 47 48 46 106 59 99 99 25 88
> print rand(2,12), rand(2^50,3^50), rand(0,2), rand(-400000, 120000) > print rand(2,12), rand(2^50,3^50), rand(0,2), rand(-400000, 120000)
11 170570393286648531699560 1 -96605 2 658186291252503497642116 1 -324097
LIMITS LIMITS
min < max min < max
@@ -248,8 +256,8 @@ SEE ALSO
## received a copy with calc; if not, write to Free Software Foundation, Inc. ## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## ##
## @(#) $Revision: 29.2 $ ## @(#) $Revision: 29.3 $
## @(#) $Id: rand,v 29.2 2000/06/07 14:02:33 chongo Exp $ ## @(#) $Id: rand,v 29.3 2001/04/14 22:46:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/rand,v $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/rand,v $
## ##
## Under source code control: 1996/01/01 02:16:09 ## Under source code control: 1996/01/01 02:16:09

View File

@@ -1,5 +1,5 @@
NAME NAME
srand - seed the additive 55 shuffle pseudo-random number generator srand - seed the subtractive 100 shuffle pseudo-random number generator
SYNOPSIS SYNOPSIS
srand([seed]) srand([seed])
@@ -10,43 +10,43 @@ TYPES
return rand state return rand state
DESCRIPTION DESCRIPTION
Seed the pseudo-random number using an additive 55 shuffle generator. Seed the pseudo-random number using an subtractive 100 shuffle generator.
For integer seed != 0: For integer seed != 0:
Any buffered rand generator bits are flushed. The additive table Any buffered rand generator bits are flushed. The subtractive table
for the rand generator is loaded with the default additive table. for the rand generator is loaded with the default subtractive table.
The low order 64 bits of seed is xor-ed against each table value. The low order 64 bits of seed is xor-ed against each table value.
The additive table is shuffled according to seed/2^64. The subtractive table is shuffled according to seed/2^64.
The following calc code produces the same effect on the internal The following calc code produces the same effect on the internal
additive table: subtractive table:
/* reload default additive table xor-ed with low 64 seed bits */ /* reload default subtractive table xor-ed with low 64 seed bits */
seed_xor = seed & ((1<<64)-1); seed_xor = seed & ((1<<64)-1);
for (i=0; i < 55; ++i) { for (i=0; i < 100; ++i) {
additive[i] = xor(default_additive[i], seed_xor); subtractive[i] = xor(default_subtractive[i], seed_xor);
} }
/* shuffle the additive table */ /* shuffle the subtractive table */
seed >>= 64; seed >>= 64;
for (i=55; seed > 0 && i > 0; --i) { for (i=100; seed > 0 && i > 0; --i) {
quomod(seed, i+1, seed, j); quomod(seed, i+1, seed, j);
swap(additive[i], additive[j]); swap(subtractive[i], subtractive[j]);
} }
Seed must be >= 0. All seed values < 0 are reserved for future use. Seed must be >= 0. All seed values < 0 are reserved for future use.
The additive table pointers are reset to additive[23] and additive[54]. The subtractive table pointers are reset to subtractive[36]
Last the shuffle table is loaded with successive values from the and subtractive[99]. Last the shuffle table is loaded with
additive 55 generator. successive values from the subtractive 100 generator.
There is no limit on the size of a seed. On the other hand, There is no limit on the size of a seed. On the other hand,
extremely large seeds require large tables and long seed times. extremely large seeds require large tables and long seed times.
Using a seed in the range of [2^64, 2^64 * 55!) should be Using a seed in the range of [2^64, 2^64 * 100!) should be
sufficient for most purposes. An easy way to stay within this sufficient for most purposes. An easy way to stay within this
range to to use seeds that are between 21 and 93 digits, or range to to use seeds that are between 21 and 178 digits, or
64 to 308 bits long. 64 to 588 bits long.
To help make the generator produced by seed S, significantly To help make the generator produced by seed S, significantly
different from S+1, seeds are scrambled prior to use. The different from S+1, seeds are scrambled prior to use. The
@@ -68,9 +68,9 @@ DESCRIPTION
After this call, the rand generator is restored to its initial After this call, the rand generator is restored to its initial
state after calc started. state after calc started.
The additive 55 pointers are reset to additive[23] and additive[54]. The subtractive 100 pointers are reset to subtractive[36]
Last the shuffle table is loaded with successive values from the and subtractive[99]. Last the shuffle table is loaded with
additive 55 generator. successive values from the subtractive 100 generator.
The call: The call:
@@ -80,14 +80,14 @@ DESCRIPTION
For matrix arg: For matrix arg:
Any buffered random bits are flushed. The additive table with the Any buffered random bits are flushed. The subtractive table with the
first 55 entries of the matrix mod 2^64. first 100 entries of the matrix mod 2^64.
The additive 55 pointers are reset to additive[23] and additive[54]. The subtractive 100 pointers are reset to subtractive[36]
Last the shuffle table is loaded with successive values from the and subtractive[99]. Last the shuffle table is loaded with
additive 55 generator. successive values from the subtractive 100 generator.
This form allows one to load the internal additive 55 generator This form allows one to load the internal subtractive 100 generator
with user supplied values. with user supplied values.
The randreseed64 process is NOT applied to the matrix values. The randreseed64 process is NOT applied to the matrix values.
@@ -114,7 +114,7 @@ DESCRIPTION
For no arg given: For no arg given:
Return current a55 generator state. This call does not alter Return current s100 generator state. This call does not alter
the generator state. the generator state.
This call allows one to take a snapshot of the current generator state. This call allows one to take a snapshot of the current generator state.
@@ -126,25 +126,25 @@ EXAMPLE
RAND state RAND state
> state = srand(); > state = srand();
> print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123); > print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123);
32 60 67 71 1 77 80 95 41 78 100 27
> print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123); > print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123);
52 72 110 15 69 58 122 109 12 95 80 32
> state2 = srand(state); > state2 = srand(state);
> print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123); > print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123);
32 60 67 71 1 77 80 95 41 78 100 27
> print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123); > print rand(123), rand(123), rand(123), rand(123), rand(123), rand(123);
52 72 110 15 69 58 122 109 12 95 80 32
> state3 = srand(); > state3 = srand();
> print state3 == state2; > print state3 == state2;
1 1
> print rand(); > print rand();
641407694185874626 10710588361472584495
LIMITS LIMITS
for matrix arg, the matrix must have at least 55 integers for matrix arg, the matrix must have at least 100 integers
LINK LIBRARY LINK LIBRARY
RAND *zsrand(ZVALUE *pseed, MATRIX *pmat55) RAND *zsrand(ZVALUE *pseed, MATRIX *pmat100)
RAND *zsetrand(RAND *state) RAND *zsetrand(RAND *state)
SEE ALSO SEE ALSO
@@ -166,8 +166,8 @@ SEE ALSO
## received a copy with calc; if not, write to Free Software Foundation, Inc. ## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## ##
## @(#) $Revision: 29.2 $ ## @(#) $Revision: 29.3 $
## @(#) $Id: srand,v 29.2 2000/06/07 14:02:33 chongo Exp $ ## @(#) $Id: srand,v 29.3 2001/04/14 22:46:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/srand,v $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/srand,v $
## ##
## Under source code control: 1996/01/01 04:19:07 ## Under source code control: 1996/01/01 04:19:07

View File

@@ -17,8 +17,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.3 $ * @(#) $Revision: 29.4 $
* @(#) $Id: quickhash.c,v 29.3 2000/06/07 14:02:13 chongo Exp $ * @(#) $Id: quickhash.c,v 29.4 2001/04/14 22:47:21 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/quickhash.c,v $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/quickhash.c,v $
* *
* Under source code control: 1995/03/04 11:34:23 * Under source code control: 1995/03/04 11:34:23
@@ -304,7 +304,7 @@ objhash(OBJECT *op, QCKHASH val)
/* /*
* randhash - return a trivial hash for an a55 state * randhash - return a trivial hash for an s100 state
* *
* given: * given:
* state - state to hash * state - state to hash
@@ -326,6 +326,7 @@ randhash(RAND *r, QCKHASH val)
val = fnv(r->j, V_RAND+val); val = fnv(r->j, V_RAND+val);
val = fnv(r->k, val); val = fnv(r->k, val);
val = fnv(r->bits, val); val = fnv(r->bits, val);
val = fnv(r->need_to_skip, val);
/* hash the state arrays */ /* hash the state arrays */
return fnv_fullhash(&r->buffer[0], SLEN+SCNT+SHUFLEN, val); return fnv_fullhash(&r->buffer[0], SLEN+SCNT+SHUFLEN, val);

View File

@@ -19,8 +19,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.23 $ * @(#) $Revision: 29.24 $
* @(#) $Id: version.c,v 29.23 2001/04/10 22:13:40 chongo Exp $ * @(#) $Id: version.c,v 29.24 2001/04/14 22:56:46 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/version.c,v $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/version.c,v $
* *
* Under source code control: 1990/05/22 11:00:58 * Under source code control: 1990/05/22 11:00:58
@@ -43,7 +43,7 @@ static char *program;
#define MAJOR_VER 2 /* major version */ #define MAJOR_VER 2 /* major version */
#define MINOR_VER 11 /* minor version */ #define MINOR_VER 11 /* minor version */
#define MAJOR_PATCH 5 /* patch level or 0 if no patch */ #define MAJOR_PATCH 5 /* patch level or 0 if no patch */
#define MINOR_PATCH "2.1" /* test number or empty string if no patch */ #define MINOR_PATCH "3" /* test number or empty string if no patch */
/* /*
* calc version constants * calc version constants

1055
zrand.c

File diff suppressed because it is too large Load Diff

58
zrand.h
View File

@@ -1,5 +1,5 @@
/* /*
* zrand - additive 55 shuffle generator * zrand - subtractive 100 shuffle generator
* *
* Copyright (C) 1999 Landon Curt Noll * Copyright (C) 1999 Landon Curt Noll
* *
@@ -17,8 +17,8 @@
* received a copy with calc; if not, write to Free Software Foundation, Inc. * received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
* *
* @(#) $Revision: 29.2 $ * @(#) $Revision: 29.3 $
* @(#) $Id: zrand.h,v 29.2 2000/06/07 14:02:13 chongo Exp $ * @(#) $Id: zrand.h,v 29.3 2001/04/14 22:47:21 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/zrand.h,v $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/zrand.h,v $
* *
* Under source code control: 1995/01/07 09:45:26 * Under source code control: 1995/01/07 09:45:26
@@ -42,19 +42,19 @@
/* /*
* a55 generator defines * s100 generator defines
* *
* NOTE: SBITS must be a power of two to make the (&= (SBITS-1)) * NOTE: SBITS must be a power of two to make the (&= (SBITS-1))
* in slotcp() to work. * in slotcp() to work.
*/ */
#define SBITS (64) /* size of additive or shuffle entry in bits */ #define SBITS (64) /* size of subtractive or shuffle entry in bits */
#define SBYTES (SBITS/8) /* size of additive or shuffle entry in bytes */ #define SBYTES (SBITS/8) /* size of subtractive or shuffle entry in bytes */
#define SHALFS (SBYTES/sizeof(HALF)) /* size in HALFs */ #define SHALFS (SBYTES/sizeof(HALF)) /* size in HALFs */
/* /*
* seed defines * seed defines
*/ */
#define SEEDXORBITS 64 /* low bits of a55 seed devoted to xor */ #define SEEDXORBITS 64 /* low bits of s100 seed devoted to xor */
/* /*
* shuffle table defines * shuffle table defines
@@ -65,18 +65,18 @@
#define SHUFMASK (SHUFLEN-1) /* mask for shuffle table entry selection */ #define SHUFMASK (SHUFLEN-1) /* mask for shuffle table entry selection */
/* /*
* additive 55 constants * subtractive 100 constants
*/ */
#define A55 55 /* slots in an additive 55 table */ #define S100 100 /* slots in an subtractive 100 table */
#define INIT_J 23 /* initial first walking table index */ #define INIT_J 36 /* initial first walking table index */
#define INIT_K 54 /* initial second walking table index */ #define INIT_K 99 /* initial second walking table index */
/* /*
* additive 55 table defines * subtractive 100 table defines
* *
* SLEN - length in FULLs of an additive 55 slot * SLEN - length in FULLs of an subtractive 100 slot
* *
* SVAL(a,b) - form a 64 bit hex slot entry in the additive 55 table * SVAL(a,b) - form a 64 bit hex slot entry in the subtractive 100 table
* a: up to 8 hex digits without the leading 0x (upper half) * a: up to 8 hex digits without the leading 0x (upper half)
* b: up to 8 hex digits without the leading 0x (lower half) * b: up to 8 hex digits without the leading 0x (lower half)
* *
@@ -90,12 +90,12 @@
* *
* NOTE: Due to a SunOS cc bug, don't put spaces in the SHVAL call! * NOTE: Due to a SunOS cc bug, don't put spaces in the SHVAL call!
* *
* SLOAD(s,i,z) - load table slot i from additive 55 state s with zvalue z * SLOAD(s,i,z) - load table slot i from subtractive 100 state s with zvalue z
* s: type RAND * s: type RAND
* i: type int, s.slot[i] slot index * i: type int, s.slot[i] slot index
* z: type ZVALUE, what to load into s.slot[i] * z: type ZVALUE, what to load into s.slot[i]
* *
* SADD(s,k,j) - slot[k] += slot[j] * SSUB(s,k,j) - slot[k] -= slot[j]
* s: type RAND * s: type RAND
* k: type int, s.slot[k] slot index, what to gets changed * k: type int, s.slot[k] slot index, what to gets changed
* j: type int, s.slot[j] slot index, what to add to s.slot[k] * j: type int, s.slot[j] slot index, what to add to s.slot[k]
@@ -106,7 +106,7 @@
* k: type int, s.slot[k] slot index, selects shuffle entry * k: type int, s.slot[k] slot index, selects shuffle entry
* result type int, refers to s.shuf[SINDX(s,k)] * result type int, refers to s.shuf[SINDX(s,k)]
* *
* SBUFFER(s,t) - load a55 buffer with t * SBUFFER(s,t) - load s100 buffer with t
* s: type RAND * s: type RAND
* t: type int, s.shuf[t] entry index, replace buffer with it * t: type int, s.shuf[t] entry index, replace buffer with it
* *
@@ -130,7 +130,7 @@
* i: type int, s.slot[i] slot index, what gets xored * i: type int, s.slot[i] slot index, what gets xored
* v: type FULL*, 64 bit value to xor into s.slot[i] * v: type FULL*, 64 bit value to xor into s.slot[i]
* *
* SCNT - length of an additive 55 table in FULLs * SCNT - length of an subtractive 100 table in FULLs
*/ */
#if FULL_BITS == SBITS #if FULL_BITS == SBITS
@@ -143,7 +143,7 @@
# define SHVAL(a,b,c,d) (HALF)0x/**/c/**/d,(HALF)0x/**/a/**/b # define SHVAL(a,b,c,d) (HALF)0x/**/c/**/d,(HALF)0x/**/a/**/b
# endif # endif
#define SLOAD(s,i,z) ((s).slot[i] = ztofull(z)) #define SLOAD(s,i,z) ((s).slot[i] = ztofull(z))
#define SADD(s,k,j) ((s).slot[k] += (s).slot[j]) #define SSUB(s,k,j) ((s).slot[k] -= (s).slot[j])
#define SINDX(s,k) ((int)((s).slot[k] >> (FULL_BITS - SHUFPOW))) #define SINDX(s,k) ((int)((s).slot[k] >> (FULL_BITS - SHUFPOW)))
#define SBUFFER(s,t) {(s).buffer[0] = ((s).shuf[t] & BASE1); \ #define SBUFFER(s,t) {(s).buffer[0] = ((s).shuf[t] & BASE1); \
(s).buffer[1] = ((s).shuf[t] >> BASEB); \ (s).buffer[1] = ((s).shuf[t] >> BASEB); \
@@ -176,9 +176,9 @@
(((z).len == 3) ? (FULL)((z).v[2]) : \ (((z).len == 3) ? (FULL)((z).v[2]) : \
((FULL)((z).v[2]) + ((FULL)((z).v[3]) << BASEB)))); \ ((FULL)((z).v[2]) + ((FULL)((z).v[3]) << BASEB)))); \
} }
#define SADD(s,k,j) {FULL tmp = (s).slot[(k)<<1]; \ #define SSUB(s,k,j) {FULL tmp = (s).slot[(k)<<1]; \
(s).slot[(k)<<1] += (s).slot[(j)<<1]; \ (s).slot[(k)<<1] -= (s).slot[(j)<<1]; \
(s).slot[1+((k)<<1)] += ((tmp <= (s).slot[(k)<<1]) ? \ (s).slot[1+((k)<<1)] -= ((tmp <= (s).slot[(k)<<1]) ? \
(s).slot[1+((j)<<1)] : \ (s).slot[1+((j)<<1)] : \
(s).slot[1+((j)<<1)] + 1); \ (s).slot[1+((j)<<1)] + 1); \
} }
@@ -213,11 +213,14 @@
#endif #endif
#define SCNT (SLEN*A55) /* length of additive 55 table in FULLs */ #define SCNT (SLEN*S100) /* length of subtractive 100 table in FULLs */
#define RAND_CONSEQ_USE (100) /* use this many before skipping */
#define RAND_SKIP (1009-RAND_CONSEQ_USE) /* skip this many after use */
/* /*
* a55 generator state * s100 generator state
*/ */
struct rand { struct rand {
int seeded; /* 1 => state has been seeded */ int seeded; /* 1 => state has been seeded */
@@ -225,15 +228,16 @@ struct rand {
FULL buffer[SLEN]; /* unused random bits from last call */ FULL buffer[SLEN]; /* unused random bits from last call */
int j; /* first walking table index */ int j; /* first walking table index */
int k; /* second walking table index */ int k; /* second walking table index */
FULL slot[SCNT]; /* additive 55 table */ int need_to_skip; /* 1 => skip the next 909 values */
FULL slot[SCNT]; /* subtractive 100 table */
FULL shuf[SHUFLEN]; /* shuffle table entries */ FULL shuf[SHUFLEN]; /* shuffle table entries */
}; };
/* /*
* a55 generator function declarations * s100 generator function declarations
*/ */
extern RAND *zsrand(CONST ZVALUE *seed, CONST MATRIX *pmat55); extern RAND *zsrand(CONST ZVALUE *seed, CONST MATRIX *pmat100);
extern RAND *zsetrand(CONST RAND *state); extern RAND *zsetrand(CONST RAND *state);
extern void zrandskip(long count); extern void zrandskip(long count);
extern void zrand(long count, ZVALUE *res); extern void zrand(long count, ZVALUE *res);