[Solved] Function rnd()*20 = 20, sometimes

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
BlueSkyBlackBird
Posts: 3
Joined: Fri May 05, 2017 5:02 pm

[Solved] Function rnd()*20 = 20, sometimes

Post by BlueSkyBlackBird »

Hello everyone,
yesterday I tried to implement a dice-roller in basic and use it as a macro. That worked. Then I wanted to see how "random" the rnd() function actually is. To do that I created a function that generates a number of rolls (with a fixed die-size), writes the result into an array. Since I use a 20-sided die, I assumed that an array with 20 entries would suffice. Yet I was mistaken as I encountered out of bounds accesses. Looking deeper into this I found that my function would produce values in the range of (1:21) which was clearly not intended. However, I fail to see what this is caused by.

Code: Select all

function fnf()
Randomize
Dim value as Integer
Dim values(19) as Long

For I = 1 to 100000
	value = CInt(Int(rnd()* 20)+1)
	values(value-1)  = values(value-1) + 1
Next I

rstring = ""
For I=0 to 19
	rstring = rstring & CStr(I+1) & ":" & CStr(values(I)) & ",  "
Next I 

MsgBox rstring
End function
After testing I found that rnd()*20 results in values of 20, yet rnd() itself is never 1. The values which result in 21 seem random to me: I found a 0.98.. or a 0.67 as return value for rnd(). According to the doc, rnd() returns a Single which should be able to handle multiplication without an overflow. I assume this error is caused by some missing type conversion I simply did not do.
Last edited by BlueSkyBlackBird on Sat May 06, 2017 1:43 am, edited 3 times in total.
OpenOffice 3.1.3 Win7 x64
UnklDonald418
Volunteer
Posts: 1547
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Function rnd()*20 = 20, sometimes

Post by UnklDonald418 »

yet rnd() itself is never 1
That is incorrect, rnd() does return the value 1, thus the 21 you are seeing in your results.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
BlueSkyBlackBird
Posts: 3
Joined: Fri May 05, 2017 5:02 pm

Re: Function rnd()*20 = 20, sometimes

Post by BlueSkyBlackBird »

Again: Not according to doc. Also the 21 is produced by values other than a 1 for rnd().
OpenOffice 3.1.3 Win7 x64
UnklDonald418
Volunteer
Posts: 1547
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Function rnd()*20 = 20, sometimes

Post by UnklDonald418 »

Not according to doc.
Not sure what doc you are referring to, but it appears to be wrong. The rnd() function returns both 0 and 1. The following code will verify that though rare they are both returned.

Code: Select all

REM  *****  BASIC  *****

    function fnf()
    Randomize
    Dim value as Integer
    Dim values(20) as Long
    Dim raw 
    Dim I
    Dim test0 as integer
    Dim test1 as integer

   test0 = 0 : test1 = 0
    For I = 1 to 100000
       raw = rnd()
       if raw = 1 then
         test1 = test1 + 1
       end if
       if raw = 0 then
         test0 = test0 + 1
       end if
       value = CInt(Int(raw * 20) + 1) 
       values(value-1)  = values(value-1) + 1
    Next I
   print test0 & " 0's returned : " & test1 &  " 1's returned"
    rstring = ""
    For I=0 to 20
       rstring = rstring & CStr(I+1) & ":" & CStr(values(I)) & ",  "
    Next I

    MsgBox rstring
    End function
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
BlueSkyBlackBird
Posts: 3
Joined: Fri May 05, 2017 5:02 pm

Re: Function rnd()*20 = 20, sometimes

Post by BlueSkyBlackBird »

It looks like you were right. Testing this made also clear what the problem was. The 21 was caused by the rnd() returning one. I also tested this using a variable called rnd, coming from a java background, I did not see a problem with that. However here It seems that one can call functions without using the braces. So what really happen is that every call of rnd as variable called rnd() instead and gave me a new value.

I thank you very much and I think I can change this to [solved].
OpenOffice 3.1.3 Win7 x64
UnklDonald418
Volunteer
Posts: 1547
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: [Solved] Function rnd()*20 = 20, sometimes

Post by UnklDonald418 »

Yes, function names are reserved in Basic. When there are no arguments being passed the braces are optional. Leaving them off doesn't help much with readability.
I did a little more testing and it looks like Int() and CInt() round anything below .05 to 0.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: [Solved] Function rnd()*20 = 20, sometimes

Post by Villeroy »

You are not restricted to StarBasic. I recommend Python as macro language. The office suite comes with a Python runtime and a bridge between the Python language and the UNO API
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
Lupp
Volunteer
Posts: 3549
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: [Solved] Function rnd()*20 = 20, sometimes

Post by Lupp »

(Coming to this thread by accident researching an issue found when I tested a few lines of code written for LibO also in AOO.)

I could not find any precise specification concerning the Rnd() function in AOO Basic beyond "a random number between 0 and 1". You cannot base any reliable usage on this. It's the dull-user-way of using "between".

When testing with 10^6 calls to Rnd() in each run I got about 25 cases where the result not was distinguishable from "exactly 1" and also about 30 cases where it not was distinguishable from "exactly 0". The simple requirement to get something like a Randbetween() with integer results in Basic cannot be achieved this way without a lot of inefficient extras.

Why was this thread marked "SOLVED"? Should it signal acceptance of a suggestion like "Always use Python, never Basic."? Did somebody check Python for reliability concerning pseudo-random?

Also no solution, but good advice: Never use spreadsheets for statistical simulations!

BTW
LibO is more precise about Rnd() in Basic:
https://help.libreoffice.org/Basic/Rnd_Function_Runtime wrote:The Rnd function returns decimal fractions ranging from 0 (included) to 1 (excluded) according to a uniform distribution. It uses the Mersenne Twister 19937 random-number generator.


Of course, Rnd doesn't return anything "decimal". It works with dyadic representations. And still missing: An assurance that returned numbers always are distinguished from the upper limit by standard comparison and by the Int() function.
A test with 20000000 (20 million) calls to Rnd() un LibO did not show a failure. Shall we accept the assurance valid now?
(The test also did not return an exact 0.)
On Windows 10: LibreOffice 24.2 (new numbering) and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
JeJe
Volunteer
Posts: 2779
Joined: Wed Mar 09, 2016 2:40 pm

Re: [Solved] Function rnd()*20 = 20, sometimes

Post by JeJe »

Lupp:

This is another case of OpenOffice and LibreOffice diverging

running this code in OpenOffice yields about 30 occurrences for both 0 and 1. In LibreOffice I didn't get any for either.

Code: Select all


Sub Main
randomize
for i = 0 to 1000000
if rnd() = 1 then c= c+1 ' or if rnd() = 0 then c= c+1
next
msgbox c
End Sub

The OpenOffice help says
Rnd Function [Run-time] Returns a random number in the range 0.0 to 1.0.

Microsoft's VBA help says
"The Rnd function returns a value less than 1 but greater than or equal to zero."

I ran the test below 100000000 times in VB6 (its a lot quicker than OO!)
getting 6 for zero, none for 1, interestingly 6 also for 0.5, and 6 for 0.99 but zero again for 0.1 and 0.2.

If you want to write for more than one of these then there are other random number generators written in Basic available (may need a little adapting)

http://www.planet-source-code.com/vb/sc ... +generator
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Lupp
Volunteer
Posts: 3549
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: [Solved] Function rnd()*20 = 20, sometimes

Post by Lupp »

I superficially also reported my tests above. As I anyway started in LibO I also tested there. This partly using functions called from Calc cells (slow) and an abstract Sub (faster).

As far as I could see there was not a similar peculiarity as JeJe reported. The one mentionable observation was that no zero values at all occurred. Since there are about 10^16 distinguishable Double values in the relevant range this should be expected. In any sample 10^7 numbers from the range always "almost all" possible values should be missing.

Anyway the assurace 0<= Rnd() < 1 held for a series of tests with 10000000 (10^7) calls to Rnd() each.

LibreOffice uses the Mersenne Twister MT19937 which is widely used and well tested.
On Windows 10: LibreOffice 24.2 (new numbering) and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
Post Reply