I went back to your original code and tried to run it. I am not able to get it to return a value of 1, ever. It is the first time that I tried it.... I do see the error in my code, now that you point it out, however <blush>. Realize, however, that I am running this on a Linux box rather than a Windows box. First, I was trying using the latest dev build. I could NOT get it to return a value of 1, so I switched to the 1.1.4 release. I still can not cause it to happen.

Here is the code that determines the random numbers....

RTLFUNC(Rnd)
{
       if ( rPar.Count() > 2 )
               StarBASIC::Error( SbERR_BAD_ARGUMENT );
       else
       {
               double nRand = (double)rand();
               nRand = ( nRand / (double)RAND_MAX );
               rPar.Get(0)->PutDouble( nRand );
       }
}

Fine, so the return value depends on the compiler, because it is using the built-in rand() method. RAND_MAX is a system dependent number located in stdlib.h. rand() returns a random integer between 0 and RAND_MAX. (double) rand() / RAND_MAX has a result in the range of 0 to 1, inclusive. One more time, the value 1.0 is included in the result set. To exclude 1.0 from the result set, use (double) rand() / (RAND_MAX + 1.0 ), which excludes 1.0 from the result set. Of course, should 1.0 be exluded or should it not? I think that what you want is an enhancement, not a bug fix.

Johnny Andersson wrote:

Hi!

I always bought that one until I tried it myself. The reason why 1.0 never occurs in your modification of my code, is that you modified a > to a <...

My code:
If Value>0.99999 Then
   Count1=Count1+1
   If Value=1 Then
      Count2=Count2+1
   Endif
EndIf

Your code:
If Value<0.99999 Then
   Count1=Count1+1
   If Value=one Then
      Count2=Count2+1
   Endif
EndIf

The inner IF statement (If Value=one Then...) will never be executed since Value can never be 1.0 if Value<0.99999...
I corrected the < to a > and executed it again. The result was:

"Rnd>0.99999 occured 22 times, Rnd=1 occured 22 times. This was calculated in 130 s."

So still, no values between 0.99999 and 1.0 occured since all 22 times when Rnd>0.99999, Rnd was 1.000000...

Sorry for being such an annoying person...


Best regards
Johnny



Andrew Douglas Pitonyak <[EMAIL PROTECTED]> skrev den Fri, 20 May 2005 15:51:55 -0400:

I changed your code and recieved a very different answer. Consider the following:

Sub RndTest0
    Dim i As Long
    Dim Count1 As Long, Count2 As Long
    Dim Value As Double
    Dim one As Double
    Dim ExecTime As Long
    one = 1.0
    ExecTime=Timer
    Randomize
    For i=1 To 1000000
        Value=Rnd
        If Value<0.99999 Then
            Count1=Count1+1
            If Value=one Then
                Count2=Count2+1
            Endif
        EndIf
    Next i
    ExecTime=Timer-ExecTime
    Print "Rnd>0.99999 occured "+Count1+ _
          " times, Rnd=1 occured "+Count2+ _
          " times. This was calculated in "+ExecTime+" s."
End Sub

Note: I used type Long rather than Integer to avoid round off.
Second, I did not compare to "1", which is an integer, but rather, I stored 1.0 in a variable and compared to that. I could have also compared against "1.0". This version NEVER returns a value of 1.0.


Johnny Andersson wrote:

I found that the Rnd function returns values (0.00000... to 1.00000...), not (0.00000... to 0.99999...), which would be better in most cases.

Example:
Dim MyInteger As Integer
Dim MyArray(1 To 6) As Integer

Randomize
MyInteger=Int(6*Rnd)+1 'Supposed to return numbers 1 to 6, byt may now and then return 7. Happened to me many times. MyArray(MyInteger)=MyArray(MyInteger)+1 'Causes an error message if MyInteger>6 which may happen in this case.

In this example Rnd returns 1.

Sub RndTest
    Randomize 30091
    Print Rnd
End Sub


This example took about 2 minutes to run on my PC (450 MHz P2, a few other applications were running at the same time):

Sub RndTest0
    Dim i As Long
    Dim Count1 As Integer, Count2 As Integer
    Dim Value As Double
    Dim ExecTime As Long
        ExecTime=Timer
    Randomize
    For i=1 To 1000000
        Value=Rnd
        If Value>0.99999 Then
            Count1=Count1+1
            If Value=1 Then
                Count2=Count2+1
            Endif
        EndIf
    Next i
    ExecTime=Timer-ExecTime
Print "Rnd>0.99999 occured "+Count1+" times, Rnd=1 occured "+Count2+" times. This was calculated in "+ExecTime+" s."
End Sub

It seems like every time Rnd>0.99999 then Rnd=1, so even though Rnd produces 15 decimals it seems like only 5 (or less) are relevant. When I tried Rnd=1 at 20 to 34 occasions (different result different times of course) which indicates that Rnd=1 about once every 29000 to 50000 times.

Anyway, is Rnd=1 supposed to ever happen or is this a bug?


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


--
Andrew Pitonyak
My Macro Document: http://www.pitonyak.org/AndrewMacro.sxw
My Macro Book: http://www.hentzenwerke.com/catalog/oome.htm
Free Info:  http://www.pitonyak.org/oo.php


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to