Сгенерировать случайное число с плавающей запятой от 0 до 1

84

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

Джини
источник
1
Не дубликаты, это, похоже, единственный вопрос, явно относящийся к поплавкам.
P i

Ответы:

139

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

Немного подробнее здесь .

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

Владимир
источник
Благодарю вас. Самый прямой ответ, который я видел. Я прочитаю вашу ссылку и получу дополнительную информацию по этому поводу. Еще раз спасибо.
jini 02
3
Странно, что ARC4RANDOM_MAXнужно определять вручную, но 0x100000000это 4294967296 , то есть ULONG_MAX + 1. Где это документально подтверждено , что arc4random()Макс «s это ULONG_MAXтак или иначе?
bobobobo
@bobobobo, отсюда: developer.apple.com/library/mac/#documentation/Darwin/Reference/… Функция arc4random () возвращает псевдослучайные числа в диапазоне от 0 до (2 ** 32) -1
Владимир
8
Фактически, значение должно быть 0xFFFFFFFF, (2 ** 32) -1 == 0x100000000 - 0x1 == 0xFFFFFFFF == UINT32_MAX, как в настоящее время указано Йоргом Бюманном в ссылке.
Josejulio
1
Сгенерированные таким образом значения не гарантируют равномерного распределения!
kelin
107

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

Йован Станкович
источник
19
Это должен быть лучший ответ.
Джон Риселвато,
Возможно, вам нужно немного обновить ответ, я читал на NSHipster, который drand48необходимо инициализировать один раз с помощью семени. В документации Apple также предлагается инициализировать его.
dulaccc 02
1
Seed необходим, потому что он дает этому генератору случайных чисел отправную точку для вычислений. Без него случайная последовательность при запуске приложений всегда была бы одинаковой.
Йован Станкович
Это лучший ответ.
sabiland
Этот ответ не является оптимальным точным ответом для double. См. Stackoverflow.com/a/34765674/1033581 о том, как добиться максимальной точности.
Cœur
16

Для Swift 4.2+ см. Https://stackoverflow.com/a/50733095/1033581


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

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

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

Obj-C :

Swift :

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

  • a Float(или Float32), мантисса которого имеет значащую точность 24 бита

48-битная точность (не рекомендуется)

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

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

Swift :

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

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

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

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

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

  • a Double(или Float64) с точностью 52 бита для мантиссы
  • a, 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_uniform, randили random. Таким образом, наши 32-битные и 64-битные решения должны быть наилучшими из возможных.

Cœur
источник
«Float80» недоступен на реальных устройствах iOS (работает только на симуляторе).
Cœur
10

Эта функция также работает для отрицательных диапазонов с плавающей запятой:

Эктор Санчес
источник
4
Работа по внешнему модулю. используйте Min+(Max-Min)*((float)arc4random())/ULONG_MAXвместо этого. (float)Литая просто паранойя.
bobobobo
@bobobobo, пока я согласен с посторонним модулем, я советую делить на UINT32_MAX (всегда 4294967295) вместо ULONG_MAX (18446744073709551615 на 64 бита).
Cœur
1

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

Это создаст число от 0 до 1.

Документы BSD:

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

Лесли Годвин
источник
1

Это расширение для случайного числа Float Swift 3.1

ЯннСтеф
источник
@ Cœur Спасибо, я изменил это
YannSteph
1

Swift 4.2

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

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

Сухит Патил
источник
0

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

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

Malex
источник
В этом есть фундаментальная проблема диапазона. Это легко заметить, если вы установите для upper_bound значение 10, arc4random_uniform вернет значения от 0 до 9, а конечный результат будет от 0,0000 до 0,9000. Вместо этого вы должны разделить на upper_bound-1. Тем не менее, вы все равно будете иметь произвольно низкую точность, вызванную upper_bound, поэтому вам следует увеличить upper_bound до UINT32_MAX. И вы можете получить еще большую точность, используя arc4random()*1.0 / UINT32_MAXвместо arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1).
Cœur
-1

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

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

Гурунатха Доги
источник
Максимальное значение arc4random равно 0xFFFFFFFF
Cœur
Спасибо @ Cœur ..max val 0xFFFFFFFF, я не знал
Гурунатха Доги
ваше решение также идентично ответу Йована Станковича.
Cœur
Ох, я не видел этого @ Cœur
Gurunatha Dogi
-4

Это дает случайное число с плавающей запятой между 0 и 1. Подробнее здесь

jhilgert00
источник
3
Примечание: дает только 11 дискретных значений: 0,0, 0,1, 0,2, ..., 1,0
TalkLittle
8
Да, операция модуля сокращает результат arc4random () до значения от 0 до 10, затем он делит его на 10. Этот ответ действительно плох для общего использования.
bobobobo
-4

по умолчанию производит случайное число (с плавающей запятой) от 0 до 1.

эрагон1189
источник
4
Это дает мне случайный int.
AlexQueue 09
rand()похоже, не существует на iOS , и если бы он был, он бы выдал целое число, как и на всех других * NIX.
jscs
2
@JoshCaswell rand()является частью C, который, в свою очередь, является частью Objective-C (который используется в программировании iOS). Функции C вроде бы rand()абсолютно существуют в iOS, но arc4random()предпочтительнее.
Frungi