Jump to content


RND and RAND: Pseudorandom Number Generation by TI Basic

RND RAND pseudorandom PNG TI Basic

1 reply to this topic

#1 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,946 posts
  • Location:Silver Run, Maryland

Posted Tue Jan 16, 2018 10:25 PM

Because this topic has surfaced in several threads on this forum, I decided to give it its own thread and explain in great detail how TI Basic’s RND function and the GPL RAND function it calls 7 – 69 times work.


GPL RAND function—
RAND takes a one-byte argument (lim) that represents the limit of the pseudorandom number (PRN) that is to be returned to the caller in >8378.  RAND first generates a 16-bit PRN from the seed value (16 bits) in >83C0 as follows:
PRN = SEED * 28645 + 31417

RAND then stores the PRN thus generated back into >83C0 as the new seed. RAND next adds 1 to the limit value it was passed to use as the modulus to operate on the PRN just generated after its bytes are swapped (now PRN'). The number returned in >8378 = PRN' modulo (lim+1).

Here is the code for GPL RAND (coded in TMS9900 Assembler in Console ROM 0:
WKSC   EQU  >83C0             ISR workspace (R0 = PRN SEED)
WKSE   EQU  >83E0             GPL workspace
R5LSB  EQU  WKSE+R5+R5+1      low byte of R5 of GPL WS
RANDOM EQU  >8378             return location for RAND's PRN return byte

RAND   LI   R4,>6FE5          28645 to R4
       MPY  @WKSC,R4          SEED * 28645
       AI   R5,>7AB9          PRN = SEED * 28645 + 31417
       MOV  R5,@WKSC          PRN is stored as new SEED in >83C0
       MOVB *R13,R6           load limit number (byte) from caller to R6
       SRL  R6,8              shift to LSB
       INC  R6                make modulus (lim+1)
       CLR  R4                clear upper half of dividend
       SWPB R5                swap bytes of PRN to get PRN'
       DIV  R6,R4             perform division by modulus (lim+1)
       MOVB @R5LSB,@RANDOM    store LSB of remainder in >8378
       B    @NEXT             return to caller for next GPL instruction
TI Basic RND function—
RND takes no arguments and generates a pseudorandom number (PRN) as an 8-byte, radix-100, floating point number (0 <= PRN < 1) and stores it at FAC (>834A). RND calls GPL RAND at least 7 times, once for each radix-100 digit in the significand (7 significant radix-100 digits in mantissa) and as much as 69 times, which is extremely unlikely. RND calls RAND with a limit of 99, which is the highest value possible for a radix-100 digit.
The first PRN digit of the significand is in a loop that insures it will not be 0 unless 63 zeros in a row are returned (extremely unlikely), in which case a floating point 0 is returned as the resulting PRN.
For each time through the first-digit loop that returns 0, the excess-64 exponent that started at >3F (-1 actual exponent) is decremented by 1 and another PRN is generated. This continues until either a non-zero digit is returned or the excess-64 exponent gets to 0 (-64 actual), in which case RND exits with a floating point 0 in FAC.
If a non-zero digit is returned, that becomes the first radix-100 digit of the significand. RND then continues to get the remaining 6 radix-100 digits of the floating point number before returning to the caller.
Here is the code for TI Basic RND (coded in GPL in Console GROM 2) [Note that, where there are 2 operands, the order is destination,source.]:
RND   ST    @>834A,>3F        radix-100 exponent = -1 to FAC
      ST    @>8310,>4B        loop counter for significand starting at FAC+1
RND1  RAND  >63               get random radix-100 digit to >8378
      CZ    @>8378            0? 
      BR    GROM@RND3         no, keep current exponent and go on 
      DEC   @>834A            decrement exponent in FAC
      CZ    @>834A            0? 
      BS    GROM@RND4         exit with 0 as random number
      BR    GROM@RND1         back to exponent manipulation
RND2  RAND  >63               get random radix-100 digit to >8378
RND3  ST    *>8310,@>8378     all 7 radix-100 digits (FAC+1 to FAC+7)
      CEQ   @>8310,>51        till >8351 (FAC+8)
      BS    GROM@RNDX         exit if beyond end of number
      INC   @>8310            increase loop counter 
      BR    GROM@RND2         back to get next random digit
RND4  CLR   @>834B            set 0 
RNDX  CONT                    return to TI Basic


#2 Vorticon OFFLINE  


    River Patroller

  • 3,611 posts
  • Location:Eagan, MN, USA

Posted Wed Jan 17, 2018 8:31 AM

Great explanation Lee! I saved this for future reference. Thanks!

Also tagged with one or more of these keywords: RND, RAND, pseudorandom, PNG, TI Basic

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users