Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Inconsistency in RND
#2
Alessandro Wrote:If I write this simple program:
Code:
DIM u as UBYTE
10 let u =rnd*40
  print u
  pause 0
  if code inkey$=13 then stop
40 goto 10
a number between 0 and 40 will be shown at every pressing of ENTER.

However, inside of a larger program, this instruction:
Code:
DIM x AS UBYTE
...
x = rnd*40
always returns 38 when executed.
This might be a bug. Please provide me some code (you can do it privately, if you want). Also keep in mind that memory address 23670 and 23671 (ROM SEED variable) is also used by ZX Basic, so if something is accidentally writing there it will cause the RND sequence to repeat.
Quote:Also, the RND of the first example always returns exactly the same sequence when started afresh, at least under emulation (Spectaculator): 9, 34, 15, 7, 16, 25, 13, 37, 7, 24, 19 etc.
That's to be expected. You have to RANDOMIZE the sequence first. Use RANDOMIZE to have a different sequence each time. Since RANDOMIZE uses the system ROM timer ensure (within an emulator) that the time the program starts is always different. A trick is to ask the user to press a key before randomize, or doing it during the program main menu.
Quote:In the past I used a simple routine (by John Connolly) to generate random numbers. Here it is, modified to let it return values from 0 to 31:
Code:
LD A,R
AND %00011111
LD (address),A
When placed in a ZX-Basic listing as a subroutine, it will always return the first value. The only way to make it work is to assemble it elsewhere and call it from within ZX-BASIC with the usual RANDOMIZE USR call, then assign the PEEK [address] to a variable.
When using asm as a function, you should use FASTCALL to inline return a register. Try this:
Code:
FUNCTION FASTCALL myRND As Byte
   Asm
   ld a, r
   and 0x1F
   End Asm
END FUNCTION
Now call if with myRND (i.e. PRINT myRND).
Please tell me if this helps.
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)