RND related question

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

RND related question

Post by R-Tape »

Okayyy, I should know this by now but I'll blame it on my rusty BASIC.

I'd like to get random integers starting at 0 and up to and including 186.

Theoretically my understanding is that:

INT (RND*186)

Should do it but it never gives 186, even with the processor put up and leaving it. If I change it to:

INT (RND*187)

It gives 186, and never seems to give 187. The BASIC manual says that RND=1 is a possibility, is that right? What have I misunderstood or does RND=1 happen once in a google billion?
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

Re: RND related question

Post by AndyC »

According to Chapter 11, it can be 0 but never 1, which is how I always understood it. Since Sinclair BASIC always rounds down, RND*186 can never give 186.
User avatar
MatGubbins
Dynamite Dan
Posts: 1238
Joined: Mon Nov 13, 2017 11:45 am
Location: Kent, UK

Re: RND related question

Post by MatGubbins »

186 gives 0 to 185
If you want 186 then int (rnd*186)+1, then you should get 1 to 186
unless my basic is rusty too.
User avatar
Blerkotron
Dizzy
Posts: 90
Joined: Mon Nov 13, 2017 12:36 pm

Re: RND related question

Post by Blerkotron »

Yeah, it was always my understanding that RND returned a number of 0 or greater but always less than 1, therefore INT(RND*187) would give you what you want. If it's possible for RND to return a value of 1 I've never seen it happen!
User avatar
MonkZy
Manic Miner
Posts: 278
Joined: Thu Feb 08, 2018 1:01 pm

Re: RND related question

Post by MonkZy »

I think INT ((RND*186)+0.5) would give 0 to 186
User avatar
Einar Saukas
Bugaboo
Posts: 3070
Joined: Wed Nov 15, 2017 2:48 pm

Re: RND related question

Post by Einar Saukas »

R-Tape wrote: Sat Apr 28, 2018 6:49 pm INT (RND*186)
In theory, it generates a number from 0 to 185.

In practice, in many BASIC implementations there's a very small change of producing 186, due to floating point rounding errors.
User avatar
Einar Saukas
Bugaboo
Posts: 3070
Joined: Wed Nov 15, 2017 2:48 pm

Re: RND related question

Post by Einar Saukas »

MonkZy wrote: Sat Apr 28, 2018 7:01 pm I think INT ((RND*186)+0.5) would give 0 to 186
Yes, but values 0 and 186 would have only half the chance of any other.
User avatar
Kweepa
Manic Miner
Posts: 311
Joined: Sat Feb 03, 2018 6:14 pm
Location: Albuquerque, New Mexico

Re: RND related question

Post by Kweepa »

if you really want to bulletproof your code, then perhaps
def fn r(x)=int(rnd*(x+0.9999))
let p=fn r(186)
Or, if you can't abide the last number being marginally less probable,
let p=int(rnd*187): let p=p*(p<>187)
which will set p=0 if it ever hits 187.
I don't think these are necessary though.
Sadly the Spectrum manual suggests int(rnd(x+0.5)) :(
User avatar
Kweepa
Manic Miner
Posts: 311
Joined: Sat Feb 03, 2018 6:14 pm
Location: Albuquerque, New Mexico

Re: RND related question

Post by Kweepa »

Some more thought...
Spectrum uses RNG that produces a sequence that runs through 0-65535, which RND just divides by 65536.
You can see this by running the program:
10 print 65536*rnd:goto10
Therefore the max that RND can produce is 65535/65536=0.999984 (calc done on spectrum)
When you multiply, for example, 187 by that, you get 186.99715 (calc done on spectrum) which will never round accidentally to the higher number.
So it's perfectly safe to use INT(RND(187)) for 0-186.
User avatar
Einar Saukas
Bugaboo
Posts: 3070
Joined: Wed Nov 15, 2017 2:48 pm

Re: RND related question

Post by Einar Saukas »

Kweepa wrote: Sat Apr 28, 2018 8:34 pm Some more thought...
Spectrum uses RNG that produces a sequence that runs through 0-65535, which RND just divides by 65536.
You can see this by running the program:
10 print 65536*rnd:goto10
Therefore the max that RND can produce is 65535/65536=0.999984 (calc done on spectrum)
When you multiply, for example, 187 by that, you get 186.99715 (calc done on spectrum) which will never round accidentally to the higher number.
So it's perfectly safe to use INT(RND(187)) for 0-186.
Good point!

So it's safe specifically for Sinclair BASIC, for the wrong reason :)
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: RND related question

Post by R-Tape »

Interesting! Thanks.

I didn't unravel the maths but after a few minutes with the emulator cranked up I was fairly sure 187 was not going to appear.

INT(RND(187)) it is.
Post Reply