次の(やや非効率的な)コードがあります。
\ RNG support
VARIABLE seed
: rand ( -- random )
seed @
DUP 13 LSHIFT XOR
DUP 17 RSHIFT XOR
DUP 5 LSHIFT XOR
DUP seed ! ;
\ Checker for number of set bits
: clear-lsb ( u -- u )
DUP 1- AND ;
: under++ ( u x -- u++ x )
SWAP 1+ SWAP ;
: ones-rec ( c u -- c u | c )
?DUP ( c 0 | c u u )
0<> IF EXIT ( c | c u )
THEN under++ clear-lsb RECURSE ;
: ones-rec ( c u -- c u | c )
?DUP IF
under++ clear-lsb
RECURSE
THEN ;
: ones ( u -- n )
0 SWAP ones-rec ;
\ Makes a random number with n set bits
: rand-n-bits ( n -- random )
rand ( n random )
OVER SWAP ( n n random )
ones ( n n bits )
= ( n f )
IF EXIT
THEN RECURSE ;
私の理解では、 と の両方がRECURSE
適切なテール コールである必要があります。しかし、Gforth に を要求すると、リターン スタックがオーバーフローします。Gforth は適切なテール コールを最適化しませんか、それとも単にこれを正しく行っていないのでしょうか?rand-n-bits
ones-rec
10 rand-n-bits