84

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?

jscs
  • 63,694
  • 13
  • 151
  • 195
Strong Like Bull
  • 11,155
  • 36
  • 98
  • 169
  • 1
    Not duplicates, this appears to be the only question explicitly pertaining to floats. – P i May 29 '11 at 08:56

12 Answers12

141

Random value in [0, 1[ (including 0, excluding 1):

double val = ((double)arc4random() / UINT32_MAX);

A bit more details here.

Actual range is [0, 0.999999999767169356], as upper bound is (double)0xFFFFFFFF / 0x100000000.

orkoden
  • 18,946
  • 4
  • 59
  • 50
Vladimir
  • 170,431
  • 36
  • 387
  • 313
  • Thank You. Most straight forward answer I have seen. I will read up on your link and get additional details on this. Thanks again. – Strong Like Bull Mar 02 '11 at 19:40
  • 3
    It's weird that `ARC4RANDOM_MAX` has to be manually defined, but [`0x100000000` is 4294967296](http://www.google.com/#hl=en&q=0x100000000+in+decimal), which is [`ULONG_MAX + 1`](http://www.cplusplus.com/reference/clibrary/climits/). Where is it documented that `arc4random()`'s max is `ULONG_MAX` anyhow? – bobobobo Sep 15 '12 at 16:53
  • @bobobobo, from here: https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/arc4random.3.html The arc4random() function returns pseudo-random numbers in the range of 0 to (2**32)-1 – Vladimir Sep 15 '12 at 17:18
  • @bobobobo, although I agree that defining constant for this case does not look nice – Vladimir Sep 15 '12 at 17:18
  • 8
    Actually, the value should be 0xFFFFFFFF, (2**32)-1 == 0x100000000 - 0x1 == 0xFFFFFFFF == UINT32_MAX as currently stated by Jörg Bühmann on the link. – Josejulio Dec 10 '14 at 16:51
  • @Vladimir, What type is `ARC4RANDOM_MAX`? I want to define it as a variable. – Iulian Onofrei Jun 08 '15 at 08:55
  • @IulianOnofrei, you can declare it as unsigned long. – Vladimir Jun 08 '15 at 09:11
  • 1
    Values generated such a way are not guaranteed to be uniformly distributed! – kelin Jun 09 '15 at 08:05
  • @Josejulio, you're right, I've made a separate answer using `UINT32_MAX`: http://stackoverflow.com/a/34765674/1033581 – Cœur Jan 13 '16 at 11:39
107
// Seed (only once)
srand48(time(0));

double x = drand48();

// Swift version
// Seed (only once)
srand48(Int(Date().timeIntervalSince1970))

let x = drand48()

The drand48() and erand48() functions return non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0 , 1.0].

Jovan Stankovic
  • 4,661
  • 4
  • 27
  • 16
  • 19
    This should be the best answer. – John Riselvato Aug 22 '13 at 14:00
  • You maybe need to update just a little the answer, I [read on NSHipster](http://nshipster.com/random/#random-double-between-0-and-1) that `drand48` need to be initialized once with a seed. The [Apple documentation](https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/srand48.3.html) also suggest that it should be initialized. – dulaccc Sep 02 '14 at 13:39
  • 1
    Seed is needed because it gives this random generator a starting point for calculations. Without it random sequence would always be the same across app launches. – Jovan Stankovic Feb 04 '17 at 13:52
  • This IS the best answer. – sabiland May 26 '17 at 10:42
  • This answer is not an optimal precision answer for a `double`. See https://stackoverflow.com/a/34765674/1033581 on how to achieve best precision. – Cœur Mar 21 '18 at 01:31
  • I also think drand48() is fastest among all versions. – sabiland May 30 '23 at 09:45
15

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:

float val = (float)arc4random() / UINT32_MAX;

Swift:

let val = Float(arc4random()) / Float(UInt32.max)

It's optimal for:

  • a Float (or Float32) which has a significand precision of 24 bits for its mantissa

48 bits precision (discouraged)

It's easy to achieve 48 bits precision with drand48 (which uses arc4random_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:

// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()

64 bits precision (Optimal for Double and Float80)

Uniform random value in [0, 1] (including 0.0 and 1.0), up to 64 bits precision:

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)

It's optimal for:

  • a Double (or Float64) which has a significand precision of 52 bits for its mantissa
  • a Float80 which has a significand precision of 64 bits for its mantissa

Notes

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.

  • using arc4random(), best precision is 1 / 0xFFFFFFFF (UINT32_MAX)
  • using arc4random_uniform(), best precision is 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • using rand() (secretly using arc4random), best precision is 1 / 0x7FFFFFFF (RAND_MAX)
  • using 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 or random. So our above 32 bits and 64 bits solutions should be the best we can achieve.

Cœur
  • 37,241
  • 25
  • 195
  • 267
10

This function works for negative float ranges as well:

float randomFloat(float Min, float Max){
    return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
Héctor Sanchez
  • 137
  • 2
  • 6
  • 4
    Extraneous modulus operation. use `Min+(Max-Min)*((float)arc4random())/ULONG_MAX` instead. The `(float)` cast is just paranoia. – bobobobo Sep 15 '12 at 17:28
  • @bobobobo while I agree on the extraneous modulus, I advice to divide by UINT32_MAX (4294967295 always) instead of ULONG_MAX (18446744073709551615 on 64 bits). – Cœur Mar 21 '18 at 01:28
7

Swift 4.2+

Swift 4.2 adds native support for a random value in a Range:

let x = Float.random(in: 0.0...1.0)
let y = Double.random(in: 0.0...1.0)
let z = Float80.random(in: 0.0...1.0)

Doc:

Community
  • 1
  • 1
Cœur
  • 37,241
  • 25
  • 195
  • 267
1
(float)rand() / RAND_MAX

The previous post stating "rand()" alone was incorrect. This is the correct way to use rand().

This will create a number between 0 -> 1

BSD docs:

The rand() function computes a sequence of pseudo-random integers in the
range of 0 to RAND_MAX (as defined by the header file "stdlib.h").

Frungi
  • 506
  • 5
  • 16
Leslie Godwin
  • 2,601
  • 26
  • 18
1

This is extension for Float random number Swift 3.1

// MARK: Float Extension

public extension Float {

    /// Returns a random floating point number between 0.0 and 1.0, inclusive.
    public static var random: Float {
        return Float(arc4random()) / Float(UInt32.max))
    }

    /// Random float between 0 and n-1.
    ///
    /// - Parameter n:  Interval max
    /// - Returns:      Returns a random float point number between 0 and n max
    public static func random(min: Float, max: Float) -> Float {
        return Float.random * (max - min) + min
    }
}
YanSte
  • 10,661
  • 3
  • 57
  • 53
1

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)

let intBetween0to9 = Int.random(in: 0...9) 
let doubleBetween0to1 = Double.random(in: 0...1)

All number types have the static random(in:) function which takes the range and returns the random number in the given range.

Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
0

Use this to avoid problems with upper bound of arc4random()

u_int32_t upper_bound = 1000000;

float r = arc4random_uniform(upper_bound)*1.0/upper_bound;

Note that it is applicable for MAC_10_7, IPHONE_4_3 and higher.

malex
  • 9,874
  • 3
  • 56
  • 77
  • There is a fundamental range issue with this. It's easily noticeable when you set upper_bound to 10, arc4random_uniform will return values from 0 to 9, and final result will be from 0.0000 to 0.9000. You should instead divide by `upper_bound-1`. Yet, you would still have an arbitrarily low precision caused by upper_bound, so you should increase the upper_bound to UINT32_MAX. And you can get even better precision from using `arc4random()*1.0 / UINT32_MAX` instead of `arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1)`. – Cœur Sep 27 '17 at 05:47
-1

arc4random has a range up to 0x100000000 (4294967296)

This is another good option to generate random numbers between 0 to 1:

srand48(time(0));      // pseudo-random number initializer.
double r = drand48();
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Gurunatha Dogi
  • 341
  • 1
  • 5
  • 9
-4
rand() 

by default produces a random number(float) between 0 and 1.

eragon1189
  • 49
  • 4
  • 4
    This produces a random int for me. – AlexQueue Jan 09 '13 at 01:24
  • `rand()` doesn't [seem to exist on iOS](http://developer.apple.com/library/ios/search/?q=rand), and if it did, it would produce an integer like it does on every other *NIX. – jscs Apr 22 '13 at 05:06
  • 2
    @JoshCaswell `rand()` is part of C, which is in turn part of Objective-C (which is used in iOS programming). C functions like `rand()` absolutely exist on iOS, but `arc4random()` is preferred. – Frungi Nov 15 '13 at 21:19
-4
float x = arc4random() % 11 * 0.1;

That produces a random float bewteen 0 and 1. More info here

jhilgert00
  • 5,479
  • 2
  • 38
  • 54
  • 3
    Note: only gives 11 discrete values: 0.0, 0.1, 0.2, ..., 1.0 – TalkLittle Sep 11 '12 at 19:26
  • 8
    Yes, the modulus operation cuts arc4random()'s result to being between 0 and 10, then he divides it by 10. This answer is really bad for general use. – bobobobo Sep 13 '12 at 16:26