Generate a random float between 0 and 1

IosCRandomFloating PointArc4random

Ios Problem Overview


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?

Ios Solutions


Solution 1 - Ios

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.

Solution 2 - Ios

// 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].

Solution 3 - Ios

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.

Solution 4 - Ios

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;
}

Solution 5 - Ios

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:

Solution 6 - Ios

(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").

Solution 7 - Ios

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
    }
}

Solution 8 - Ios

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.

Solution 9 - Ios

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.

Solution 10 - Ios

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();

Solution 11 - Ios

float x = arc4random() % 11 * 0.1;

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

Solution 12 - Ios

rand() 

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjiniView Question on Stackoverflow
Solution 1 - IosVladimirView Answer on Stackoverflow
Solution 2 - IosJovan StankovicView Answer on Stackoverflow
Solution 3 - IosCœurView Answer on Stackoverflow
Solution 4 - IosHéctor SanchezView Answer on Stackoverflow
Solution 5 - IosCœurView Answer on Stackoverflow
Solution 6 - IosLeslie GodwinView Answer on Stackoverflow
Solution 7 - IosYannStephView Answer on Stackoverflow
Solution 8 - IosSuhit PatilView Answer on Stackoverflow
Solution 9 - IosmalexView Answer on Stackoverflow
Solution 10 - IosGurunatha DogiView Answer on Stackoverflow
Solution 11 - Iosjhilgert00View Answer on Stackoverflow
Solution 12 - Ioseragon1189View Answer on Stackoverflow