Я понимаю, что книга Свифта предоставила реализацию генератора случайных чисел. Является ли наилучшей практикой копировать и вставлять эту реализацию в собственную программу? Или есть библиотека, которая делает это, что мы можем использовать сейчас?
443
Используйте
arc4random_uniform(n)
для случайного целого числа от 0 до n-1.Приведите результат к Int, чтобы вам не приходилось явно вводить ваши переменные как
UInt32
(что кажется не-Swifty).источник
0
. В вашем коде,diceRoll
может быть0
. Просто говорю ...Int(arc4random_uniform(6)+1)
.arc3random_uniform(n)
a,UInt32(n)
если вы используете значение, которое еще не относится к этому типу.Редактировать: Обновлено для Swift 3.0
arc4random
хорошо работает в Swift, но базовые функции ограничены 32-битными целочисленными типами (Int
64-битные на iPhone 5S и современных Mac). Вот обобщенная функция для случайного числа типа, выражаемого целочисленным литералом:Мы можем использовать эту новую универсальную функцию для расширения
UInt64
, добавления граничных аргументов и смягчения смещения по модулю. (Это снято прямо с arc4random.c )При этом мы можем расширить
Int64
для тех же аргументов, касающихся переполнения:Чтобы завершить семью ...
После всего этого мы можем наконец сделать что-то вроде этого:
источник
var r = arc4random(UInt64)
. Пожалуйста, посоветуйте, что вы здесь имели в виду?arc4random
(определенной в первом блоке кода) с аргументомUInt64
aType
.arc4random_buf
. Цель этих расширений состоит в том, чтобы делать именно то, чтоarc4random_uniform
делает (смягчать смещение по модулю), за исключением 64-битных типов.Редактировать для Swift 4.2
Начиная с Swift 4.2, вместо использования импортированной функции C arc4random_uniform (), теперь вы можете использовать собственные встроенные функции Swift.
Вы можете использовать,
random(in:)
чтобы получить случайные значения для других примитивных значений; такие как Int, Double, Float и даже Bool.Swift версии <4.2
Этот метод будет генерировать случайное
Int
значение между заданным минимумом и максимумомисточник
Я использовал этот код:
источник
random is unavailable in Swift: Use arc4random instead.
Начиная с iOS 9, вы можете использовать новые классы GameplayKit для генерации случайных чисел различными способами.
У вас есть четыре типа источников на выбор: общий случайный источник (без имени, вплоть до системы, чтобы выбрать, что он делает), линейный конгруэнтный, ARC4 и Mersenne Twister. Они могут генерировать случайные целые числа, числа с плавающей запятой и значения типа bools.
На простейшем уровне вы можете сгенерировать случайное число из встроенного в систему случайного источника, например:
Это создает число от -2 147 483 648 до 2 147 483 647. Если вы хотите число от 0 до верхней границы (исключая), вы должны использовать это:
В GameplayKit есть несколько удобных конструкторов для работы с кубиками. Например, вы можете бросить шестигранный кубик так:
Кроме того, вы можете формировать случайное распределение, используя такие вещи, как GKShuffledDistribution. Это займет немного больше объяснений, но если вам интересно, вы можете прочитать мой учебник по случайным числам GameplayKit .
источник
import GameplayKit
. Swift 3 изменил синтаксис наGKRandomSource.sharedRandom().nextInt(upperBound: 6)
Вы можете сделать это так же, как в C:
randomNumber
выводится как типUInt32
(32-разрядное целое число без знака)источник
rand
,arc4random
,drand48
и друзья все вDarwin
модуле. Он уже импортирован для вас, если вы создаете приложение Cocoa, UIKit или Foundation, но вам это нужно наimport Darwin
игровых площадках.использование
arc4random_uniform()
Применение:
arc4random_uniform(someNumber: UInt32) -> UInt32
Это дает вам случайные целые числа в диапазоне
0
доsomeNumber - 1
.Максимальное значение для
UInt32
4,294,967,295 (то есть2^32 - 1
).Примеры:
Подбрасывание монет
Кубик ролл
Случайный день в октябре
Случайный год в 1990-х
Общая форма:
где
number
,max
иmin
естьUInt32
.Что о...
arc4random ()
Вы также можете получить случайное число с помощью
arc4random()
, который производитUInt32
от 0 до 2 ^ 32-1. Таким образом, чтобы получить случайное число между0
иx-1
, вы можете разделить его наx
и взять остаток. Или, другими словами, используйте оператор остатка (%) :Однако это приводит к небольшому смещению по модулю (см. Также здесь и здесь ), поэтому
arc4random_uniform()
рекомендуется.Преобразование в и из
Int
Обычно это было бы хорошо , чтобы сделать что - то вроде этого, чтобы преобразовать обратно и вперед между
Int
иUInt32
:Проблема, однако, заключается в том, что он
Int
имеет диапазон-2,147,483,648...2,147,483,647
на 32-битных системах и диапазон-9,223,372,036,854,775,808...9,223,372,036,854,775,807
на 64-битных системах. Сравните это сUInt32
ассортиментом0...4,294,967,295
.U
ИзUInt32
средств без знака .Рассмотрим следующие ошибки:
Так что вам просто нужно быть уверенным, что ваши входные параметры находятся в пределах
UInt32
диапазона и что вам также не нужен выход, выходящий за пределы этого диапазона.источник
Пример для случайного числа между 10 (0-9);
Очень простой код - простой и короткий.
источник
Я был в состоянии просто использовать,
rand()
чтобы получить случайный CInt. Вы можете сделать это Int, используя что-то вроде этого:Вы можете использовать свою любимую C-случайную функцию и просто конвертировать ее в значение Int, если это необходимо.
источник
random()
, который возвращаетInt
скорее, чемUInt32
- и, как упомянуто @SomeGuy, просто вызыватьsrandom(arc4random())
один раз в любом месте, прежде чем использовать его, чтобы убедиться, что он имеет различное, рандомизированное начальное число для каждого выполнения вашей программы.Ответ @ jstn хорош, но немного многословен. Swift известен как протоколно-ориентированный язык, поэтому мы можем достичь того же результата, не прибегая к реализации стандартного кода для каждого класса в целочисленном семействе, добавив реализацию по умолчанию для расширения протокола.
Теперь мы можем сделать:
и все другие целочисленные классы в порядке.
источник
В Swift 4.2 вы можете генерировать случайные числа, вызывая
random()
метод для любого числового типа, который вам нужен, предоставляя диапазон, с которым вы хотите работать. Например, при этом генерируется случайное число в диапазоне от 1 до 9 включительно с обеих сторон.Также с другими типами
источник
Вот библиотека, которая хорошо справляется со своей задачей https://github.com/thellimist/SwiftRandom
источник
источник
Я хотел бы добавить к существующим ответам, что пример генератора случайных чисел в книге Свифта - это Линейный генератор конгруэнтности (LCG), он строго ограничен и не должен быть исключением за исключением тривиальных примеров, где качество случайности не не имеет значения вообще. И LCG никогда не должен использоваться в криптографических целях .
arc4random()
намного лучше и может использоваться для большинства целей, но опять же не должен использоваться в криптографических целях.Если вы хотите что-то гарантированно криптографически безопасное, используйте
SecCopyRandomBytes()
. Обратите внимание, что если вы встраиваете генератор случайных чисел во что-то, кто-то другой может (неправильно) использовать его для криптографических целей (таких как генерация пароля, ключа или соли), тогда вам следует рассмотреть возможность использования вSecCopyRandomBytes()
любом случае, даже если ваша потребность не Это вполне необходимо.источник
поскольку Swift 4.2
Существует новый набор API:
Все числовые типы теперь имеют
random(in:)
метод, который принимаетrange
.Возвращает число, равномерно распределенное в этом диапазоне.
TL; DR
Ну, что не так с «старым добрым» способом?
Вы должны использовать импортированные C API-интерфейсы (они отличаются для разных платформ) .
И более того...
Если вы используете
arc4random()
(чтобы вычислить остаток) какarc4random() % aNumber
, результат не будет равномерно распределен между0
иaNumber
. Существует проблема, которая называется смещением по модулю .Модульный уклон
Как правило, функция генерирует случайное число между
0
и MAX (зависит от типа и т.д.) . Для быстрого и простого примера, скажем, максимальное число равно,7
и вы заботитесь о случайном числе в диапазоне0 ..< 2
(или интервале [0, 3), если вы предпочитаете это) .Эти вероятности для отдельных чисел:
Другими словами, у вас больше шансов получить 0 или 1, чем 2 . Конечно, нужно помнить, что это чрезвычайно упрощено, а число MAX намного выше, что делает его более «справедливым».
источник
Без arc4Random_uniform () в некоторых версиях Xcode (в 7.1 он запускается, но не выполняет автозаполнение для меня). Вы можете сделать это вместо этого.
Для генерации случайного числа от 0-5. Первый
затем
источник
Здесь 5 убедится, что случайное число генерируется от нуля до четырех. Вы можете установить значение соответственно.
источник
Swift 4.2
Пока, чтобы импортировать Фонд C lib
arc4random_uniform()
Подробнее @ Официальный
источник
Следующий код создаст безопасное случайное число от 0 до 255:
Вы называете это так:
Для больших чисел это становится более сложным.
Это лучшее, что я мог придумать:
Эти методы используют дополнительное случайное число, чтобы определить, сколько
UInt8
s будет использоваться для создания случайного числа. Последняя строка преобразует[UInt8]
вUInt16
илиUInt32
.Я не знаю, считаются ли последние два действительно случайными, но вы можете настроить их по своему вкусу :)
источник
Swift 4.2
Swift 4.2 включил в стандартную библиотеку нативный и довольно полнофункциональный API случайных чисел. ( Предложение Swift Evolution SE-0202 )
Все типы чисел имеют статическое случайное число (in :), которое принимает диапазон и возвращает случайное число в данном диапазоне.
источник
Для iOS, macOS и tvOS вы можете использовать общесистемный случайный источник в платформе XCode
GameKit
. Здесь вы можете найтиGKRandomSource
класс с егоsharedRandom()
методом класса:Или просто используйте
randomElement()
метод, который возвращает случайный элемент коллекции:источник
Вы можете использовать
GeneratorOf
как это:источник
Я использую этот код для генерации случайного числа:
источник
подробности
xCode 9.1, Swift 4
Математическое решение (1)
Использование раствора (1)
Решение для программистов (2)
Использование решения (2)
Полный образец
Пример результата
источник