I am trying to make a static extension of Bool
to return a random true/false value whenever called. I am trying to make this work:
static func coinFlip() -> Bool {
#if os(Linux)
srand(UInt32(time(nil)))
let result = Int(random() % 2)
if result == 0 {
return false
} else {
return true
}
#else
return arc4random_uniform(2) == 0
#endif
}
I am using this within the scope of a route being called in a Server Side Swift application. Whenever it is called for the first time, it does return a random value, but all subsequent calls to the function in the same scope don't randomize the output. For example:
for _ in 1...5 {
let coin = Bool.coinFlip()
if coin == true {
print("coin flip true")
} else {
print("coin flip false")
}
}
...yields an output of this:
coin flip false
coin flip false
coin flip false
coin flip false
coin flip false
...but then if I call the route again separately, I could get:
coin flip true
coin flip true
coin flip true
coin flip true
coin flip true
Is it a problem with srand(UInt32(time(nil)))
only randomizing the pseudo-random sequence of random()
? I'm not sure what to do. Thanks in advance for your help!
time(nil))
returns the current time as a number of seconds, which means that
you seed the random number generator with the same value when
the method is called multiple times within a one second interval.
You should call srand(UInt32(time(nil)))
only once on application
startup, not on each call of coinFlip()
.
In addition, the function can be simplified a bit, and I would call
it random()
, not coinFlip()
:
#if os(Linux)
srand(UInt32(time(nil)))
#endif
extension Bool {
static func random() -> Bool {
#if os(Linux)
return Glibc.random() % 2 == 0
#else
return arc4random_uniform(2) == 0
#endif
}
}
for _ in 1...5 {
print(Bool.random())
}