RND related question

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

RND related question

Post by R-Tape » Sat Apr 28, 2018 5:49 pm

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?
0 x

AndyC
Manic Miner
Posts: 251
Joined: Mon Nov 13, 2017 5:12 am

Re: RND related question

Post by AndyC » Sat Apr 28, 2018 5:53 pm

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.
0 x

User avatar
MatGubbins
Manic Miner
Posts: 537
Joined: Mon Nov 13, 2017 11:45 am
Location: Kent, UK

Re: RND related question

Post by MatGubbins » Sat Apr 28, 2018 5:54 pm

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.
0 x
Bomb Munchies Ver1930 17th Nov 2017 (look for the blue download box ) If you get a time-out message and live in the UK then try after 9pm-3am.
Send me a PM and I can email it to you too. Kent, UK

User avatar
Blerkotron
Dizzy
Posts: 90
Joined: Mon Nov 13, 2017 12:36 pm

Re: RND related question

Post by Blerkotron » Sat Apr 28, 2018 5:59 pm

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!
0 x

User avatar
MonkZy
Dizzy
Posts: 89
Joined: Thu Feb 08, 2018 1:01 pm

Re: RND related question

Post by MonkZy » Sat Apr 28, 2018 6:01 pm

I think INT ((RND*186)+0.5) would give 0 to 186
0 x

User avatar
Einar Saukas
Manic Miner
Posts: 949
Joined: Wed Nov 15, 2017 2:48 pm

Re: RND related question

Post by Einar Saukas » Sat Apr 28, 2018 6:08 pm

R-Tape wrote:
Sat Apr 28, 2018 5: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.
0 x

User avatar
Einar Saukas
Manic Miner
Posts: 949
Joined: Wed Nov 15, 2017 2:48 pm

Re: RND related question

Post by Einar Saukas » Sat Apr 28, 2018 6:10 pm

MonkZy wrote:
Sat Apr 28, 2018 6: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.
0 x

Kweepa
Manic Miner
Posts: 216
Joined: Sat Feb 03, 2018 6:14 pm
Location: Austin, Texas

Re: RND related question

Post by Kweepa » Sat Apr 28, 2018 7:22 pm

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)) :(
0 x

Kweepa
Manic Miner
Posts: 216
Joined: Sat Feb 03, 2018 6:14 pm
Location: Austin, Texas

Re: RND related question

Post by Kweepa » Sat Apr 28, 2018 7: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.
1 x

User avatar
Einar Saukas
Manic Miner
Posts: 949
Joined: Wed Nov 15, 2017 2:48 pm

Re: RND related question

Post by Einar Saukas » Sat Apr 28, 2018 7:56 pm

Kweepa wrote:
Sat Apr 28, 2018 7: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 :)
0 x

Post Reply