[swift-users] arc4random_uniform on Linux is missing from Foundation??
Jens Persson
jens at bitcycle.com
Tue May 23 05:18:26 CDT 2017
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 <jens at 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 <jens at 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 at swift.org> wrote:
>>
>>>
>>> Saagar Jha
>>>
>>> On May 22, 2017, at 08:44, Edward Connell via swift-users <
>>> swift-users at 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 at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170523/c821a91e/attachment.html>
More information about the swift-users
mailing list