mirror of
https://github.com/zsh-users/zsh
synced 2024-07-21 18:24:18 +00:00
16241: new rand48(param) math function
This commit is contained in:
parent
096e24858f
commit
b0c56c0561
|
@ -1,3 +1,9 @@
|
|||
2001-11-15 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 16241: zshconfig.ac, Src/Modules/mathfunc.c,
|
||||
Doc/Zsh/mod_mathfunc.yo: new rand48(param) math function calls
|
||||
erand48(3), storing seed as hex string in $param.
|
||||
|
||||
2001-11-14 Andrej Borsenkow <bor@zsh.org>
|
||||
|
||||
* 16247: Completion/Mandrake/Command/_urpmi: completion
|
||||
|
|
|
@ -52,3 +52,36 @@ a floating point or integer value (by truncation) respectively.
|
|||
|
||||
Note that the C tt(pow) function is available in ordinary math evaluation
|
||||
as the `tt(**)' operator and is not provided here.
|
||||
|
||||
The function tt(rand48) is available if your system's mathematical library
|
||||
has the function tt(erand48(3)). It returns a pseudo-random floating point
|
||||
number between 0 and 1. It takes a single string optional argument.
|
||||
|
||||
If the argument is not present, the random number seed is initialised by
|
||||
three calls to the tt(rand(3)) function --- this produces the same random
|
||||
numbers as the next three values of tt($RANDOM).
|
||||
|
||||
If the argument is present, it gives the name of a scalar parameter where
|
||||
the current random number seed will be stored. On the first call, the
|
||||
value must contain at least twelve hexadecimal digits (the remainder of the
|
||||
string is ignored), or the seed will be initialised in the same manner as
|
||||
for a call to tt(rand48) with no argument. Subsequent calls to
|
||||
tt(rand48)LPAR()var(param)RPAR() will then maintain the seed in the
|
||||
parameter var(param) as a string of twelve hexadecimal digits, with no base
|
||||
signifier. The random number sequences for different parameters are
|
||||
completely independent, and are also independent from that used by calls to
|
||||
tt(rand48) with no argument.
|
||||
|
||||
For example, consider
|
||||
|
||||
example(print $(( rand48(seed) ))
|
||||
print $(( rand48() ))
|
||||
print $(( rand48(seed) )))
|
||||
|
||||
Assuming tt($seed) does not exist, it will be initialised by the first
|
||||
call. In the second call, the default seed is initialised; note, however,
|
||||
that because of the properties of tt(rand()) there is a correlation between
|
||||
the seeds used for the two initialisations, so for more secure uses, you
|
||||
should generate your own 12-byte seed. The third call returns to the same
|
||||
sequence of random numbers used in the first call, unaffected by the
|
||||
intervening tt(rand48()).
|
||||
|
|
|
@ -82,6 +82,12 @@ MF_Y1,
|
|||
MF_YN
|
||||
};
|
||||
|
||||
/* also functions taking a string argument */
|
||||
|
||||
enum {
|
||||
MS_RAND48
|
||||
};
|
||||
|
||||
/*
|
||||
* also to do, but differently argument or returned: abs (no type
|
||||
* conversion), atan2.
|
||||
|
@ -119,6 +125,12 @@ enum {
|
|||
|
||||
|
||||
static struct mathfunc mftab[] = {
|
||||
/* Functions taking string arguments */
|
||||
#ifdef HAVE_ERAND48
|
||||
/* here to avoid comma hassle */
|
||||
STRMATHFUNC("rand48", math_string, MS_RAND48),
|
||||
#endif
|
||||
|
||||
NUMMATHFUNC("abs", math_func, 1, 1, MF_ABS | BFLAG(BF_FRAC) |
|
||||
TFLAG(TF_NOCONV|TF_NOASS)),
|
||||
NUMMATHFUNC("acos", math_func, 1, 1, MF_ACOS | BFLAG(BF_FRAC)),
|
||||
|
@ -448,6 +460,100 @@ math_func(char *name, int argc, mnumber *argv, int id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**/
|
||||
static mnumber
|
||||
math_string(char *name, char *arg, int id)
|
||||
{
|
||||
mnumber ret = zero_mnumber;
|
||||
char *send;
|
||||
/*
|
||||
* Post-process the string argument, which is just passed verbatim.
|
||||
* Not clear if any other functions that use math_string() will
|
||||
* want this, but assume so for now.
|
||||
*/
|
||||
while (iblank(*arg))
|
||||
arg++;
|
||||
send = arg + strlen(arg);
|
||||
while (send > arg && iblank(send[-1]))
|
||||
send--;
|
||||
*send = '\0';
|
||||
|
||||
switch (id)
|
||||
{
|
||||
#ifdef HAVE_ERAND48
|
||||
case MS_RAND48:
|
||||
{
|
||||
static unsigned short seedbuf[3];
|
||||
static int seedbuf_init;
|
||||
unsigned short tmp_seedbuf[3], *seedbufptr;
|
||||
int do_init = 1;
|
||||
|
||||
if (*arg) {
|
||||
/* Seed is contained in parameter named by arg */
|
||||
char *seedstr;
|
||||
seedbufptr = tmp_seedbuf;
|
||||
if ((seedstr = getsparam(arg)) && strlen(seedstr) >= 12) {
|
||||
int i, j;
|
||||
do_init = 0;
|
||||
/*
|
||||
* Decode three sets of four hex digits corresponding
|
||||
* to each unsigned short.
|
||||
*/
|
||||
for (i = 0; i < 3 && !do_init; i++) {
|
||||
unsigned short *seedptr = seedbuf + i;
|
||||
*seedptr = 0;
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (*seedstr >= '0' && *seedstr <= '9')
|
||||
*seedptr += *seedstr - '0';
|
||||
else if (tolower(*seedstr) >= 'a' &&
|
||||
tolower(*seedstr) <= 'f')
|
||||
*seedptr += tolower(*seedstr) - 'a' + 10;
|
||||
else {
|
||||
do_init = 1;
|
||||
break;
|
||||
}
|
||||
seedstr++;
|
||||
if (j < 3)
|
||||
*seedptr *= 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (errflag)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use default seed: must be initialised. */
|
||||
seedbufptr = seedbuf;
|
||||
if (!seedbuf_init)
|
||||
seedbuf_init = 1;
|
||||
else
|
||||
do_init = 1;
|
||||
}
|
||||
if (do_init) {
|
||||
seedbufptr[0] = (unsigned short)rand();
|
||||
seedbufptr[1] = (unsigned short)rand();
|
||||
seedbufptr[2] = (unsigned short)rand();
|
||||
}
|
||||
ret.type = MN_FLOAT;
|
||||
ret.u.d = erand48(seedbufptr);
|
||||
|
||||
if (*arg)
|
||||
{
|
||||
char outbuf[13];
|
||||
sprintf(outbuf, "%04x%04x%04x", (int)seedbufptr[0],
|
||||
(int)seedbufptr[1], (int)seedbufptr[2]);
|
||||
setsparam(arg, ztrdup(outbuf));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**/
|
||||
int
|
||||
setup_(Module m)
|
||||
|
|
|
@ -938,7 +938,8 @@ AC_CHECK_FUNCS(strftime difftime gettimeofday \
|
|||
brk sbrk \
|
||||
pathconf sysconf \
|
||||
tgetent tigetflag tigetnum tigetstr setupterm \
|
||||
pcre_compile pcre_study pcre_exec)
|
||||
pcre_compile pcre_study pcre_exec \
|
||||
erand48)
|
||||
AC_FUNC_STRCOLL
|
||||
|
||||
dnl Check if tgetent accepts NULL (and will allocate its own termcap buffer)
|
||||
|
|
Loading…
Reference in a new issue