#define randval (RSCALE*(k_random=(RANDA*k_random+RANDC)&MAXLONG))
* ?x - produce a randomly selected element of x.
random(nargs
, arg1v
, arg1
, arg0
)
struct descrip arg1v
, arg1
, arg0
;
register union block
*bp
;
if (QUAL(arg1
)) { /* random char in string */
if ((val
= STRLEN(arg1
)) <= 0)
hneed(sizeof(struct b_tvsubs
));
mksubs(&arg1v
, &arg1
, (int)(randval
*val
)+1, 1, &arg0
);
if ((val
= STRLEN(arg1
)) <= 0)
STRLOC(arg0
) = alcstr(STRLOC(arg1
)+(int)(randval
*val
), 1);
r1
= BLKLOC(arg1
)->realval
;
if (r1
< 0 || r1
> MAXSHORT
)
if (val
== 0) /* return real in range [0,1) */
else /* return integer in range [1,val] */
mkint((long)(randval
*val
) + 1, &arg0
);
i
= (int)(randval
*val
) + 1;
bp
= BLKLOC(BLKLOC(arg1
)->list
.listhead
);
while (i
>= j
+ bp
->listb
.nused
) {
if (TYPE(bp
->listb
.listnext
) != T_LISTB
)
syserr("list reference out of bounds in random");
bp
= BLKLOC(bp
->listb
.listnext
);
i
+= bp
->listb
.first
- j
;
if (i
>= bp
->listb
.nelem
)
dp
= &bp
->listb
.lelem
[i
];
arg0
.type
= D_VAR
+ ((int *)dp
- (int *)bp
);
i
= (int)(randval
*val
) + 1;
for (j
= 0; j
< NBUCKETS
; j
++) {
for (ep
= BLKLOC(bp
->table
.buckets
[j
]); ep
!= NULL
;
ep
= BLKLOC(ep
->telem
.blink
)) {
arg0
.type
= D_VAR
+ ((int *)dp
- (int *)bp
);
val
= bp
->record
.recptr
->nfields
;
dp
= &bp
->record
.fields
[(int)(randval
*val
)];
arg0
.type
= D_VAR
+ ((int *)dp
- (int *)bp
);
struct b_iproc Brandom
= {