For Swift 4.2+ see: stack overflow.site/questions/71372 / ...
The following are recommendations for proper uniformity and optimal accuracy for ObjC and Swift 4.1.
Accuracy 32 bits (optimal for Float )
Uniform random value in [0, 1] (including 0.0 and 1.0) with an accuracy of 32 bits:
Obj-C :
float val = (float)arc4random() / UINT32_MAX;
Swift :
let val = Float(arc4random()) / Float(UInt32.max)
Optimal for:
Float (or Float32 ), which has significance and accuracy of 24 bits for its mantissa
48 bit accuracy (not recommended)
With drand48 it is easy to achieve an accuracy of 48 bits ( which uses arc4random_buf under the hood ). But note that drand48 has flaws due to the need for seed, and also because it is not optimal for randomizing all 52 bits of a double mantissa.
Uniform random value in [0, 1] , accuracy 48 bits:
Swift :
// seed (only needed once) srand48(Int(Date.timeIntervalSinceReferenceDate)) // random Double value let val = drand48()
Accuracy 64 bits (optimal for Double and Float80 )
Uniform random value in [0, 1] (including 0.0 and 1.0) with an accuracy of 64 bits:
Swift using two calls to arc4random:
let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random()) let val = Float80(arc4random64) / Float80(UInt64.max)
Swift using one call to arc4random_buf:
var arc4random64: UInt64 = 0 arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64)) let val = Float80(arc4random64) / Float80(UInt64.max)
Optimal for:
Double (or Float64 ), which has significance and accuracy of 52 bits for its mantissaFloat80 which matters and accuracy of 64 bits for its mantissa
Notes
Comparison with other methods
Answers where the range excludes one of the boundaries (0 or 1) are likely to suffer from uniformity bias and should be avoided.
- using
arc4random() , best accuracy 1 / 0xFFFFFFFF (UINT32_MAX) - using
arc4random_uniform() , the best accuracy is 1 / 0xFFFFFFFE (UINT32_MAX-1) - using
rand() ( secretly using arc4random ), the best precision is 1 / 0x7FFFFFFF (RAND_MAX) - using
random() ( secretly using arc4random ), best accuracy 1 / 0x7FFFFFFF (RAND_MAX)
It is mathematically impossible to achieve better accuracy than 32- arc4random with a single call to arc4random , arc4random_uniform , rand or random . Thus, our aforementioned 32-bit and 64-bit solutions should be the best we can achieve.
Cœur Jan 13 '16 at 11:36 2016-01-13 11:36
source share