Сгенерировать случайное число с плавающей запятой от 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-битные решения должны быть наилучшими из возможных.


«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 и выше.


В этом есть фундаментальная проблема диапазона. Это легко заметить, если вы установите для 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. Подробнее здесь


3
Примечание: дает только 11 дискретных значений: 0,0, 0,1, 0,2, ..., 1,0
— TalkLittle

8
Да, операция модуля сокращает результат arc4random () до значения от 0 до 10, затем он делит его на 10. Этот ответ действительно плох для общего использования.
— bobobobo

-4

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


4
Это дает мне случайный int.
— AlexQueue 09

rand()похоже, не существует на iOS , и если бы он был, он бы выдал целое число, как и на всех других * NIX.
— jscs

2
@JoshCaswell rand()является частью C, который, в свою очередь, является частью Objective-C (который используется в программировании iOS). Функции C вроде бы rand()абсолютно существуют в iOS, но arc4random()предпочтительнее.
— Frungi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.