Перейти к содержимому
  • 0
ArtHacker

Как получить случайное целое число?

Вопрос

Как получить рандомное число?

Просто math.random() в конце ещё .0 добавляет. Нам не нужно дробное число.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

  • math.random() генерирует псевдослучайное вещественное число в диапазоне[0 до 1]
  • math.random(upper) генерирует целое число в диапазоне [1..upper];
  • math.random(lower, upper) генерирует целое число в диапазоне [lower..upper].
Изменено пользователем eu_tomat
псевдослучайное число

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, ArtHacker сказал:

Просто math.random() в конце ещё .0 добавляет. Нам не нужно дробное число.

можно использовать math.floor()

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 минуты назад, 8urton сказал:

можно использовать math.floor()

Можно. Но для какой цели?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, eu_tomat сказал:

Можно. Но для какой цели?

Разве math.floor() не делает из 4.0 - 4?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, 8urton сказал:

Разве math.floor() не делает из 4.0 - 4?

Да, делает. Мой вопрос оказался не по адресу. Тут кто как понял вопрос автора, тот так на него и ответил.

 

А вопрос автора оказался неоднозначным. Потому как math.random возвращает либо целое число, которое изначально не требует дополнительного округления,  либо возвращает вещественное число, отбросив дробную часть которого, мы всегда будем получать ноль.

 

1 час назад, ArtHacker сказал:

Просто math.random() в конце ещё .0 добавляет. Нам не нужно дробное число.

А в какой версии Lua так происходит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, eu_tomat сказал:

А в какой версии Lua так происходит?

Видимо, в 5.2, где еще не выделен int. Хотя в 5.2 у ТС не возникли бы проблемы с этим

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
29 минут назад, hohserg сказал:

Видимо, в 5.2, где еще не выделен int. Хотя в 5.2 у ТС не возникли бы проблемы с этим

В 5.2 тоже нормально:

$ lua5.2 -e 'print(math.random(),math.random(5))'
0.84018771715471	2
$ lua5.3 -e 'print(math.random(),math.random(5))'
0.84018771676347	2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 22.11.2019 в 17:35, eu_tomat сказал:
  • math.random() генерирует случайное вещественное число в диапазоне[0 до 1]
  • math.random(upper) генерирует целое число в диапазоне [1..upper];
  • math.random(lower, upper) генерирует целое число в диапазоне [lower..upper].

Псевдо-случайное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
15 минут назад, NEO сказал:

Псевдо-случайное.

Исправил. Кстати, пост выше чётко демонстрирует отсутствие настоящей случайности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
5 часов назад, eu_tomat сказал:

Исправил. Кстати, пост выше чётко демонстрирует отсутствие настоящей случайности.

Ради интереса посмотрел код, луа использует свою реализацию алгоритма для расчёта псевдо-случайных чисел. Вырезал весь код который относится к генерации числа, ссылка на код https://hastebin.com/arudubohot.c

 

P.S

Это задел на Lua 5.4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, eu_tomat сказал:

Исправил. Кстати, пост выше чётко демонстрирует отсутствие настоящей случайности.

Ну это всегда и везде же так.

Именно поэтому нужен метод math.randomseed(...).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
36 минут назад, Totoro сказал:

Ну это всегда и везде же так.

Именно поэтому нужен метод math.randomseed(...).

Не всегда и не везде. Например:

$ lua5.2 -e 'print(math.random(),math.random(5))'
0.84018771715471        2
$ lua5.2 -e 'print(math.random(),math.random(5))'
0.84018771715471        2

$ python -c 'import random;print random.random()'
0.721716743456
$ python -c 'import random;print random.random()'
0.0560445795169

Как можно видеть, python как-то сам инициализирует генерацию ПСЧ. Насколько случайно зерно, и берёт ли python энтропию из системы, я не проверял.

 

Зато неслучайность генерации ПСЧ на Lua обнаруживается даже примитивным экспериментом. А насколько случайно зерно в randomseed, это отдельный вопрос. В большинстве случаев кода его значение тоже далеко от случайного:

$ lua5.2 -e 'math.randomseed(100500)print(math.random())'
0.58517133751194
$ lua5.2 -e 'math.randomseed(100500)print(math.random())'
0.58517133751194

Замена зерна на os.time() тоже не много меняет, хотя и добавляет чуть-чуть случайности. Но совсем немного:

$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.26793141616508
$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.68165180506185
$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.68165180506185
$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.094727045390755
$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.094727045390755
$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.094727045390755
$ lua5.3 -e 'math.randomseed(os.time())print(math.random())'
0.0091965580359101

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
31 минуту назад, eu_tomat сказал:

Замена зерна на os.time() тоже не много меняет, хотя и добавляет чуть-чуть случайности. Но совсем немного:

Ну, во-первых, вызывать randomseed перед каждым вызовом random не нужно. Сид - это некий оффсет для псевдослучайной функции, один раз задав его, дальше можно получать последовательные псевдо-случайные числа как обычно (и они будут отличатся от полученных без сида).

Во-вторых, функция os.time() возвращает время в секундах, поэтому, очевидно, что задавая оффсет и дергая генератор с частотой выше чем в секунду - получаешь одни и те же числа.

В случае майнкрафта этот эффект в 20 раз менее заметен, потому что функция os.time() там переопределена, чтобы возвращать время в тиках.

 

Ну а что касается Питона, он просто сам задаёт сид основанный на времени. Насколько я знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, Totoro сказал:

Ну, во-первых, вызывать randomseed перед каждым вызовом random не нужно.

А кто утверждал, что нужно вызывать перед каждым? Приведённые примеры демонстрируют высокую степень предопределённости первого числа. Остальные числа также предопределены, это легко проверяется. Изначально речь шла о том, что именно в Lua эта предопределённость заметна невооружённым глазом, в отличие, например от Python.

2 минуты назад, Totoro сказал:

Ну а что касается Питона, он просто сам задаёт сид основанный на времени. Насколько я знаю.

Возможно, там присутствуют миллисекунды или микросекунды, и я физически не смог запустить скрипт с такой точностью. В серьёзных задачах такая случайность тоже может не играть решающей роли, поэтому есть, например, /dev/random. Его, конечно, тоже можно хакнуть, но это уже лежит на ответственности админа, допускающего подключение устройств, способных выдавать себя за достоверные источники энтропии. А источники энтропии существуют. По крайней мере, на существующем технологическом этапе они могут считаться таковыми.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

если вызвать randomseed без аргументов он берёт для генератора два сида - это time(NULL) и адрес lua_State

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 минут назад, NEO сказал:

если вызвать randomseed без аргументов он берёт для генератора два сида - это time(NULL) и адрес lua_State

У меня этот трюк не проходит:

$ lua5.2 -e 'math.randomseed()print(math.random())'
lua5.2: (command line):1: bad argument #1 to 'randomseed' (number expected, got no value)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 минут назад, eu_tomat сказал:

У меня этот трюк не проходит:


$ lua5.2 -e 'math.randomseed()print(math.random())'
lua5.2: (command line):1: bad argument #1 to 'randomseed' (number expected, got no value)

 

Про это забыл, сиё уже фичи автора на версию 5.4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я вот не знаю, но у меня код компилируется с постоянными разными числами

 

Код:

for i = 1,5 do
    print(math.random())
    end

Ответ компилятора:

0.66925806894856
0.3032681871235
0.64422552876116
0.64007273039517
0.16843780872441

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Joe Числа из одной последовательности и должны быть разными, как правило. Выше речь шла не о совпадении чисел внутри последовательности, а о совпадении самих последовательностей с момента запуска Lua.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

Держи готовую функцию. for i = 1, 8 do: здесь поменяй 8, на большее число, если нужно что бы рандомное возвращаемое число было больше. 

function rand()
	local res = ""
	for i = 1, 8 do
		res = res .. string.char(math.random(48, 57))
	end
	return tonumber(res)
end

 

Изменено пользователем num_pi

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...