I'm trying to generate a random number that's between 0 and 1. I keep reading about arc4random()
, but there isn't any information about getting a float from it. How do I do this?
相关问题
- Multiple sockets for clients to connect to
- Core Data lightweight migration crashes after App
- What is the best way to do a search in a large fil
- How can I implement password recovery in an iPhone
- State preservation and restoration strategies with
Swift 4.2+
Swift 4.2 adds native support for a random value in a Range:
Doc:
random(in range: ClosedRange<Float>)
random(in range: Range<Float>)
random(in range: ClosedRange<Double>)
random(in range: Range<Double>)
random(in range: ClosedRange<Float80>)
random(in range: Range<Float80>)
How about this operation
((CGFloat)(rand()%100)/100)
?That produces a random float bewteen 0 and 1. More info here
For Swift 4.2+ see: https://stackoverflow.com/a/50733095/1033581
Below are recommendations for correct uniformity and optimal precision for ObjC and Swift 4.1.
32 bits precision (Optimal for
Float
)Uniform random value in [0, 1] (including 0.0 and 1.0), up to 32 bits precision:
Obj-C:
Swift:
It's optimal for:
Float
(orFloat32
) which has a significand precision of 24 bits for its mantissa48 bits precision (discouraged)
It's easy to achieve 48 bits precision with
drand48
(which usesarc4random_buf
under the hood). But note that drand48 has flaws because of the seed requirement and also for being suboptimal to randomize all 52 bits of Double mantissa.Uniform random value in [0, 1], 48 bits precision:
Swift:
64 bits precision (Optimal for
Double
andFloat80
)Uniform random value in [0, 1] (including 0.0 and 1.0), up to 64 bits precision:
Swift, using two calls to arc4random:
Swift, using one call to arc4random_buf:
It's optimal for:
Double
(orFloat64
) which has a significand precision of 52 bits for its mantissaFloat80
which has a significand precision of 64 bits for its mantissaNotes
Comparisons with other methods
Answers where the range is excluding one of the bounds (0 or 1) likely suffer from a uniformity bias and should be avoided.
arc4random()
, best precision is 1 / 0xFFFFFFFF (UINT32_MAX)arc4random_uniform()
, best precision is 1 / 0xFFFFFFFE (UINT32_MAX-1)rand()
(secretly using arc4random), best precision is 1 / 0x7FFFFFFF (RAND_MAX)random()
(secretly using arc4random), best precision is 1 / 0x7FFFFFFF (RAND_MAX)It's mathematically impossible to achieve better than 32 bits precision with a single call to
arc4random
,arc4random_uniform
,rand
orrandom
. So our above 32 bits and 64 bits solutions should be the best we can achieve.Swift 4.2
Swift 4.2 has included a native and fairly full-featured random number API in the standard library. (Swift Evolution proposal SE-0202)
All number types have the static random(in:) function which takes the range and returns the random number in the given range.