Я пытаюсь создать случайное число, которое находится между 0 и 1. Я продолжаю читать о arc4random()
, но нет никакой информации о получении от него float. Как это сделать?
Сгенерировать случайное поплавок между 0 и 1
Ответ 1
Случайное значение в [0, 1 [ (включая 0, исключая 1):
double val = ((double)arc4random() / UINT32_MAX);
Чуть подробнее здесь.
Фактический диапазон равен [0, 0,9999999996767169356], поскольку верхняя граница равна (двойной) 0xFFFFFFFF/0x100000000.
Ответ 2
// 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].
Ответ 3
Для Swift 4. 2+ см.: fooobar.com/questions/71372/...
Ниже приведены рекомендации по правильной однородности и оптимальной точности для 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)
Оптимально для:
-
Float
(илиFloat32
), который имеет значимость и точность 24 бит для своей мантиссы
Точность 48 бит (не рекомендуется)
С drand48
легко достичь точности 48 бит (которая использует 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 бит:
Swift, используя два вызова arc4random:
let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / Float80(UInt64.max)
Swift, используя один вызов arc4random_buf:
var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)
Оптимально для:
-
Double
(илиFloat64
), который имеет значимость и точность 52 бит для своей мантиссы -
Float80
который имеет значение и точность 64 бит для своей мантиссы
Заметки
Сравнение с другими методами
Ответы, где диапазон исключает одну из границ (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
, arc4random_uniform
, rand
или random
. Таким образом, наши вышеупомянутые 32-битные и 64-битные решения должны быть лучшими, которые мы можем достичь.
Ответ 4
Эта функция работает и с отрицательными диапазонами с плавающей запятой:
float randomFloat(float Min, float Max){
return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
Ответ 5
Свифт 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:
Ответ 6
(float)rand() / RAND_MAX
Предыдущий пост с указанием "rand()" был некорректным. Это правильный способ использования rand().
Это создаст число между 0 → 1
BSD docs:
Функция rand() вычисляет последовательность псевдослучайных целых чисел в диапазон от 0 до RAND_MAX (как определено в файле заголовка "stdlib.h" ).
Ответ 7
Это расширение для случайного числа 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
}
}
Ответ 8
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 :), которая берет диапазон и возвращает случайное число в данном диапазоне.
Ответ 9
Используйте это, чтобы избежать проблем с верхней границей arc4random()
u_int32_t upper_bound = 1000000;
float r = arc4random_uniform(upper_bound)*1.0/upper_bound;
Обратите внимание, что он применим для MAC_10_7, IPHONE_4_3 и выше.
Ответ 10
Как насчет этой операции ((CGFloat)(rand()%100)/100)
?
Ответ 11
arc4random
имеет диапазон до 0x100000000 (4294967296)
Это еще одна хорошая возможность генерировать случайные числа от 0 до 1:
srand48(time(0)); // pseudo-random number initializer.
double r = drand48();
Ответ 12
float x = arc4random() % 11 * 0.1;
Это создает случайное значение float, равное 0 и 1. Подробнее здесь
Ответ 13
rand()
по умолчанию создает случайное число (float) между 0 и 1.