Just for the heck of it I am buying this true random generator.
https://www.amazon.com/TrueRNG-V3-Ha.../dp/B01KR2JHTA
The device sends bytes over the comport that are random.
To get a head start I thought I would try and mimic what the Random class does. At the core of Random is the .Sample method. And right from go I am confused.
How do you create a Double greater than or equal to 0 and less than one from 8 random bytes? I have some code that appears to work but is slow, 6 seconds to produce 1,000,000 Doubles.
Until I get the device I am filling the comport buffer with random bytes using the Random class.Code:' Significand or mantissa 0-51
' Exponent 52 - 62
' Sign (0 = Positive, 1 = Negative) 63
' 8000000000000
Me._methodLock.WaitOne() 'for thread safety
Dim rv As Double = Double.NaN
Const MantMsk As Long = &HFFFFFFFFFFFFFL
Const ExpMsk As Long = &H7FF0000000000000L
Const Mask As Long = MantMsk Or ExpMsk 'negative numbers not possible with this mask
Dim L As Long = Long.MinValue
If Me.WaitForBytes(8) Then 'wait for there to be at least 8 bytes in the com buffer
Dim byteVal As New List(Of Byte)
Do While byteVal.Count < 8 'get eight bytes from the com buffer
Dim b As Byte
If Me.buf.TryDequeue(b) Then
byteVal.Add(b)
End If
Loop
' L is a long
L = Mask And BitConverter.ToInt64(byteVal.ToArray, 0)
Do
Dim ct As Integer = 0
rv = BitConverter.ToDouble(BitConverter.GetBytes(L), 0)
'1.#QNAN
If Double.IsInfinity(rv) OrElse
Double.IsNaN(rv) OrElse
Double.IsNegativeInfinity(rv) OrElse
Double.IsPositiveInfinity(rv) Then
L = L Xor Long.MinValue
ElseIf rv >= 0.0R AndAlso rv < 1.0R Then '
Exit Do 'success
End If
ct += 1
Dim foo As Long = L
Dim exp As Long = (foo And ExpMsk) >> 52
exp = (exp << 51) And ExpMsk
foo = (foo And MantMsk)
foo = foo Or exp
L = foo
Loop
Else
'todo
Stop
End If

