Sorry for the premature send ...
Here is the site: http://xoroshiro.di.unimi.it
There is also a section there about "generating uniform doubles in unit
interval" which is worth reading.
And here's how to get uniform floating point values in the range [0, 1)
from various (supposedly) random bit patterns:
extension Double {
init(unitRange v: UInt64) {
let shifts: UInt64 = 63 - UInt64(Double.significandBitCount)
self = Double(v >> shifts) * (.ulpOfOne/2)
}
init(unitRange v: UInt32) {
self = (Double(v) + 0.5) / (Double(UInt32.max) + 1.0)
}
init(unitRange v: UInt16) {
self = (Double(v) + 0.5) / (Double(UInt16.max) + 1.0)
}
init(unitRange v: UInt8) {
self = (Double(v) + 0.5) / (Double(UInt8.max) + 1.0)
}
}
extension Float {
init(unitRange v: UInt64) {
let shifts: UInt64 = 63 - UInt64(Float.significandBitCount)
self = Float(v >> shifts) * (.ulpOfOne/2)
}
init(unitRange v: UInt32) {
let shifts: UInt32 = 31 - UInt32(Float.significandBitCount)
self = Float(v >> shifts) * (.ulpOfOne/2)
}
init(unitRange v: UInt16) {
let a = Float(v) + 0.5
let b = Float(UInt16.max) + 1.0
self = a / b
}
init(unitRange v: UInt8) {
let a = Float(v) + 0.5
let b = Float(UInt8.max) + 1.0
self = a / b
}
}
You will get a very fast and good quality prng using xoroshiro, converting
to unit range floating point and then back to uniform range int if you want
to, much much faster than arc4random.
/Jens
···
On Mon, May 22, 2017 at 11:17 PM, Jens Persson <jens@bitcycle.com> wrote:
Check out the generators (especially xoroshiro) on this site:
On Mon, May 22, 2017 at 6:54 PM, Saagar Jha via swift-users < > swift-users@swift.org> wrote:
Saagar Jha
On May 22, 2017, at 08:44, Edward Connell via swift-users < >> swift-users@swift.org> wrote:
Any ideas when Foundation on Linux will support arc4random_uniform? This
is kind of an important function.
There doesn't seem to be any decent substitute without requiring the
installation of libbsd-dev, which turns out to be messy. Currently I am
doing this, but glibc random with mod does not produce good quality
numbers, due to modulo bias.
Modulo bias is easy to deal with, though, if you force random to produce
a range that is a multiple of the range that you’re trying to produce:
guard range > 0 else { return 0 }
var random: Int
repeat {
random = Int(random())
} while(random > LONG_MAX / range * range)
return random % range
Has anyone come up with a better solution to get a true uniform
distribution that isn't super messy?
import Foundation
if os(Linux)
import Glibc
#endif
public func random_uniform(range: Int) -> Int {
guard range > 0 else { return 0 }
if os(Linux)
return Int(random()) % range
#else
return Int(arc4random_uniform(UInt32(range)))
#endif
}
Thanks, Ed
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users