Here's a stripped down verison of my implementation of the Xoroshiro128+ PRNG: https://gist.github.com/anonymous/527602968812f853d6147aea8c66d660
/Jens On Mon, May 22, 2017 at 11:21 PM, Jens Persson <j...@bitcycle.com> wrote: > 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 <j...@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 >>> >>> >> >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users