Генерирует случайный float между 0 и 1

Я пытаюсь генерировать случайные числа между 0 и 1. Я продолжаю читать о arc4random(), но нет никакой информации о получении поплавок от него. Как мне это сделать?

13 ответов


случайное значение в [0, 1[ (включая 0, исключая 1):

#define ARC4RANDOM_MAX      0x100000000
...
double val = ((double)arc4random() / ARC4RANDOM_MAX);

немного больше деталей здесь.

фактический диапазон составляет [0, 0.999999999767169356], поскольку верхняя граница (двойная) 0xFFFFFFFF / 0x100000000.


// Seed (only once)
srand48(time(0));

double x = drand48();

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

let x = drand48()

функции drand48() и erand48() возвращают неотрицательные значения двойной точности с плавающей запятой, равномерно распределенные по интервалу [0.0, 1.0].


для Swift 4.2 + см.:https://stackoverflow.com/a/50733095/1033581


Ниже приведены рекомендации по правильной однородности и оптимальной точности для ObjC и Swift 4.1.

точность 32 битов (оптимальная для Float)

равномерное случайное значение в [0, 1] (включая 0.0 и 1.0), до 32 бит точность:

Obj-C:

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

Свифт:

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

оптимально для:

  • a Float (или Float32) который имеет точность significand 24 битов для своей мантиссы

точность 48 битов (обескураженная)

легко достигнуть точности 48 битов с drand48 (использует arc4random_buf под капотом). Но обратите внимание, что drand48 имеет недостатки из-за требования к семени, а также для того, чтобы быть неоптимальным рандомизировать все 52 бита двойной мантиссы.

равномерное случайное значение в [0, 1], 48 бит точность:

Свифт:

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

точность 64 битов (оптимальная для Double и Float80)

равномерное случайное значение в [0, 1] (включая 0.0 и 1.0), до 64 бит точность:

Свифт, используя два вызова arc4random:

let val = Float80(UInt64(arc4random()) << 32 &+ UInt64(arc4random())) / Float80(UInt64.max)

Свифт, используя один вызов arc4random_buf:

var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)

оптимально для:

  • a Double (или Float64), который имеет точность мантисса 52 бита для мантиссы
  • a Float80 который имеет точность significand 64 битов для своего мантисса!--50-->

Примечания

сравнение с другими методами

ответы, где диапазон исключает одну из границ (0 или 1), вероятно, страдают от смещения однородности и их следует избегать.

  • используя arc4random(), лучшая точность-1 / 0xFFFFFFFF (UINT32_MAX)
  • используя arc4random_uniform(), лучшая точность-1 / 0xFFFFFFFE (UINT32_MAX-1)
  • используя rand() (тайно, используя arc4random), лучшая точность - 1 / 0x7FFFFFFF (RAND_MAX)
  • используя random() (секретно используя arc4random), лучшая точность - 1 / 0x7FFFFFFF (RAND_MAX)

математически невозможно достичь более 32-битной точности с помощью одного вызова arc4random, arc4random_uniform, rand или random. Таким образом, наши выше 32-битные и 64-битные решения должны быть лучшими, которых мы можем достичь.


эта функция работает и для отрицательных диапазонов float:

float randomFloat(float Min, float Max){
    return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}

(float)rand() / RAND_MAX

Предыдущее сообщение с указанием" rand () " было неверным. Это правильный способ использования rand ().

Это создаст число между 0 - > 1

BSD docs:

функция RAND() вычисляет последовательность псевдослучайных целых в
диапазон от 0 до RAND_MAX (определяется заголовочным файлом " stdlib.ч.)"


Это расширение для случайного числа Float 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
    }
}

Swift 4.2

Swift 4.2 включил собственный и довольно полнофункциональный API случайных чисел в стандартную библиотеку. (предложение Swift Evolution SE-0202)

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

все типы чисел имеют статический random (in:) функция, которая принимает диапазон и возвращает случайное число в заданном диапазоне.


Swift 4.2+

Swift 4.2 добавляет встроенную поддержку случайного значения в диапазоне:

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:


использовать это, чтобы избежать проблем с верхней границей arc4random()

u_int32_t upper_bound = 1000000;

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

обратите внимание, что он применим для MAC_10_7, IPHONE_4_3 и выше.


Как насчет этой операции ((CGFloat)(rand()%100)/100) ?


arc4random имеет диапазон до 0x100000000 (4294967296)

это еще один хороший вариант для генерации случайных чисел от 0 до 1:

srand48(time(0));      // pseudo-random number initializer.
double r = drand48();

float x = arc4random() % 11 * 0.1;

который производит случайный поплавок bewteen 0 и 1. подробнее здесь


rand() 

по умолчанию создает случайное число (float) между 0 и 1.