Тёмный

Ужас и боль Math.random в JavaScript. Исследуем статистику массива 

WebDev с нуля. Канал Алекса Лущенко
Просмотров 19 тыс.
50% 1

Курс JS: js.itgid.info
Курс вестки: html.itgid.info
Интернет магазин на Node: node.itgid.info
Плейлист: goo.gl/63osiv
Телеграм: t.me/jsrules
Мои курсы: itgid.info
Делаем статистику массива и изучаем Math.random в JavaScript

Опубликовано:

 

2 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 80   
@uncle-xxi
@uncle-xxi 5 лет назад
Ошибка в том, что Math.round пользуется, т.е. число от 0 до 1 округляется то к 0 то к 1. Нужно всегда вместе с Math.round использовать только Math.floor, тогда все от 0 до 1 упадет в 0, от 1 до 2 в 2 и т.д., и выборка будет от 0 до 9, т.е. ровно 10 значений. Короче говоря в этом видео есть огромная логическая ошибка и оно, по факту, ниочем.
@loa2395
@loa2395 Год назад
Фух, ты мой спаситель, я уже подумал что мой проект по моделированию на основе формул при генерации слуайных данных был написан неправильно
@vitaliysmirnov6076
@vitaliysmirnov6076 Год назад
Math.floor от 1 до 2 выведет 2??? Floor же в меньшую округляет!?
@inikonelectrix2349
@inikonelectrix2349 6 месяцев назад
абсолютно верно. С первых секунд ролика, как только увидел этот график, так сразу понял ошибку)
@SerzhNesteruk
@SerzhNesteruk 6 месяцев назад
Согласен. Но кроме этого меня ещё смущает постоянное использование "грязных функций". Поддержка проекта даже среднего размера, где ни одна функция не является "чистой", - это просто адище. Такой код невозможно покрыть юнит-тестами, крайне трудно отлаживать, расширять и рефакторить. Это действительно ужас и боль. 😰
@alegerov9825
@alegerov9825 5 лет назад
Random умножать на 10.99, вместо Round использовать Floor. Round отсекает у 0 и 10 половину поля значений, поэтому и получается их частота вдвое ниже остальных.
@faust2134
@faust2134 5 лет назад
Именно. Придумали проблему из ничего
@leksanders8908
@leksanders8908 5 лет назад
@@igormikailov4200 =)))))))
@faust2134
@faust2134 5 лет назад
напишите это в консоли, внимание на результат. let data = Array(10).fill(0) for (let i = 0; i < 999999; i ++) { rand = Math.floor(Math.random() * 10) data[rand]++ } data Всё дело в Math.round. Более того. всё работает правильно и так, как и задумано. Это не проблема random или round
@faust2134
@faust2134 5 лет назад
Об"ясню подробнее, что бы все поняли.... Каким образом у нас получаются цифры от 1 - 9? Округление. К примеру выпадают числа: 0.5 - будет 1. 1.4999 - будет 1. Вполне нормальный диапазон [0.5, 1.5). Ноль получается всё так же, округление. 0.4999..... - будет 0. А всё выше - будет 1. Итого диапазон для нуля у нас [0, 0.5) Для 10 это работает так же Вот и об"яснение "сломанного рандома"
@alexredcross
@alexredcross 5 лет назад
Спасибо) реально думал что вся проблема в математическом округлении)
@виртуоз_ру
@виртуоз_ру 5 лет назад
@@faust2134 У тебя слово выводится с ошибкой, надо так: объяснение
@ДмитрийХорькин
@ДмитрийХорькин 5 лет назад
Да уж, прикинь, об этом этот чувак ещё и ролик загрузил, и говорит, что Math.random некорректен. Действительно, если бы человек знал как работает Math.floor, то смог бы понять, что по статистике Math.random работает корректно и выдаёт "хорошее" равномерное распределение от 0 до 1. Тупо тер вер надо учить.
@magik6831
@magik6831 5 лет назад
Случайно упал взгляд на время и 7 утра) Этот человек любит свою работу, однозначно! Дай Бог Вам здоровья!)))
@magik6831
@magik6831 3 года назад
@Ramon Gustavo wow, I didn't know, thanks))
@H336-p1v
@H336-p1v 5 лет назад
*Как насчёт увеличить шрифт?* А то с телефона не шибко удобно смотреть :
@liskorsbi
@liskorsbi 5 лет назад
Я с телефона смотрю и все норм, мб у тебя телефон слишком маленький?
@H336-p1v
@H336-p1v 5 лет назад
владислав Ковалев Телефон у меня.. да,маленький, не спорю. Но всё же удобнее с большим шрифтом.
@АйПад-Два
@АйПад-Два 4 года назад
Поддерживаю,у меня не маленький телефон(A50) и все равно неудобно
@vozay
@vozay 5 лет назад
Генерировать на два числа больше необходимого и отбрасывать крайние значения.
@nun8930
@nun8930 5 лет назад
Так а как правильно генерировать через Math.floor?
@andreychekan9908
@andreychekan9908 3 года назад
В діапазоні від 0 до 10 включно потрібно так Math.floor((10*Math.random())+1); Юзабельніть Round в іншому (на відео все видно), а от Math.ceil((11*Math.random())-1) більш природно показує результат на графіках.
@divocean4085
@divocean4085 5 лет назад
Более того, псевдорандомность math.random заключается ещё и в том, что одинаковые числа часто выпадают подряд друг за другом. Например 7, 7, 8, 8, 8, 6, 6 и т.д, что происходит из-за округления дробной части.
@korop5851
@korop5851 5 лет назад
Если округлить 8.59 будет 9, если округлить 9.42 будет 9. А если округлить 9.60 будет 10, но а 10.25 (например) мы округилть не можем, потому что такого числа у нас не может быть. У 0 и 10 шанс в 2 раза меньше. Поэтому нам надо Math.random() умножать на 11 и отнимать 0.5, и тогда наше случайное число будет от -0.5 до 10.5, и тогда 10 и 0 будут выпадать с одинаковой частотой как и другие числа.
@lorspace8318
@lorspace8318 8 месяцев назад
искал этот коммент
@delayLama_ru
@delayLama_ru 5 лет назад
Так, а как правильно то генератор чисел делать? Чтоб поровну чисел получалось..
@k.marchenko
@k.marchenko 5 лет назад
Он приводил сайт в видео. Там 3 способа
@oleg_maksiuta
@oleg_maksiuta 5 лет назад
Самый простой способ - делать тоже самое, только для округления использовать Math.floor вместо Math.round. В таком случае будут равномерно сгенерированны числа от минимального (включительно) до максимального (не включительно)
@ОксанаХарченко-д9г
спасибо, за хорошее объяснение, но в конце я ожидала вариант решения в вашей подаче
@holodina
@holodina Месяц назад
Мы можем генерировать число в диапозоне и всё, никакой проблемы. ~~(Math.random() * (max - min + 1)) + min;
@uracan7872
@uracan7872 5 лет назад
Спасибо большое , отличный пример !!
@justandrew4275
@justandrew4275 5 лет назад
Здравствуйте, Александр, нигде не могу найти, как зарегистрироваться на вашем сайте ддя прохождения бесплатного курса. Нашел только, как залогиниться, но не зарегистрироваться. Или же курс рассчитан на тех, кто уже купил хоть 1?
@ДмитрийНалетов-ч2т
Неправильное округление. Диапазон значений для 1 и 10 вдвое короче. Округляйте вниз.
@Sergey-wo3vu
@Sergey-wo3vu Год назад
Если знать математику и тервер ничего удивительного в работе рандомных генераторов в ЯП нет. Они работают, как и должны работать. Но многие даже не подозревают, что нельзя их использовать, к примеру, для выбора победителя в розыгрышах.
@slapiinf518
@slapiinf518 5 лет назад
Добрый день, Александр. Не могли бы Вы записать урок, как сделать QUIZ. И по завершению отправить ответы на почту. Спасибо.
@uncle-xxi
@uncle-xxi 5 лет назад
зачем перебор, сразу в генераторе стату надо считать было :)
@denismerigold486
@denismerigold486 5 лет назад
please! сделайте курс по python
@watsontv5834
@watsontv5834 5 лет назад
Спасибо за Ваши уроки. Снимите пожалуйста видео по парсингу на node.js
@purel2449
@purel2449 5 лет назад
yesli nujen algoritm randoma to mojesh ispolzuvat eto
@denisoleksyuk5346
@denisoleksyuk5346 3 года назад
так а почему так происходит? Я пропустил объяснение?
@freshmotion5401
@freshmotion5401 5 лет назад
Спасибо за уроки.и помощь в понимании JavaScript.
@slovesnov
@slovesnov 3 года назад
x=10*Math.random() - это случайное число 0
@hachiko489
@hachiko489 5 лет назад
*Расскажите о "self" в JavaScript*
@luricsapi3070
@luricsapi3070 5 лет назад
Self - это по сути название переменной, которой присваивается this. Место self может быть любое название переменной , с присваиванием переменной связанно использование основного контекста внутри вложенной функции. Если нужны примеры, могу объяснить на пальцах
@Юрий-р9в8д
@Юрий-р9в8д 5 лет назад
ребята помогите решить пожалуйста На вход подается фраза на русском языке, содержащая числительное. Например, "Я хочу квартиру за 10.5 миллионов" или "Мне нравится когда моя машина, стоимостью сотку штук баксов, мелькает по телевизору". Необходимо выделить числительное в форме натурального числа и вернуть.
@lekca216
@lekca216 5 лет назад
А что тут писать, всего-то указать соответствие для всех возможных слов, обозначающих числа, во всех возможных формах, типа "миллион" && "миллионов"&& "миллиона" && "лимон" && "лимонов" && "лимона" && "лям" && "лямов" && "ляма" && "мульт" && "мульта" && "мультов", ставишь в соответствие к умножению на 1,000,000 и перебираешь строки, аналогично со словами вроде "сотку" или "штук", само собой не забудь поставить проверки контекста, ведь "штук" может означать 1, а может и 1000, да и не каждый лимон должен стать миллионом, помни об этом)) И да прибудет с тобой терпение)
@назаркоцюба-э2п
@назаркоцюба-э2п 5 лет назад
круто спасибо . Больше таких видосов
@olegBilyi-n4j
@olegBilyi-n4j 2 года назад
Дякую
@dmitryn.9765
@dmitryn.9765 2 года назад
вся вышеописанная программа в вашей православной консоли с одной строки let stat=[]; for( let i=0; i
@utlookworld5784
@utlookworld5784 3 года назад
Задачи по массивами обычно решаю круглосуточно.. Если мне какая-то задачка попадется, то я даже уснуть не могу - она у меня в голове крутится и крутится. Пока в голове решение не созреет, не могу заснуть :(
@DrZlad
@DrZlad 5 лет назад
Спасибо огромное за урок. Но: момент настройки графика, сорвал последовательность восприятия самой сути урока, я тут же потерял фокус восприятия, и перефокусировался на настройки графика- и получился урок: физики+ рисования, вроде и связь есть, но всё о разном))) Успехов Вам!!!
@ПростоАмби
@ПростоАмби 5 лет назад
Друзья, подскажите пожалуйста логику этого цикла: for (var i = 0; i < a.length; i++) { if (stat[a[i]]) { stat[a[i]]++; } else { stat[a[i]] = 1; }; }; Никак не могу понять: получается, у нас 100 итераций. Первый проход берёт первое число из массива (допустим, число 5) и подставляет его в условие: if (stat[5]) { stat[5]++;} ... Видимо я туповат, не могу понять, что проверяет if? Как это выражение (if (stat[a[i]]) ) можно написать более развернуто? Типа if (stat[a[i]] == a[i]) ... тогда было бы понятнее, а так не могу понять что с чем сравнивает, ведь изначально в объекте stat = {} у нас вообще ничего нет.
@someonesomeone8668
@someonesomeone8668 5 лет назад
Если вкратце, то браузер пытается опустить код в if () до примитива true или false. Если в if () передана пустая строка - false. Если длина строки >= 1 - true. Тоже самое приключается и с цифрами. 0 - false, все остальные - true. А вот теперь ваш случай. Когда мы создаём объект и обращаемся к не присвоеному имени, брауер возвращает undifined. Undifined в if () опускается до false, любое другое число (Кроме 0) к true. В вашем примере происходит простая проверка, на не равенство к undifined (Или как говорят, на проверка на существование). Тоесть это можно расписать как if (typeof stat[a[i]] !== 'undefined')
@ПростоАмби
@ПростоАмби 5 лет назад
@@someonesomeone8668 Если код проверяет только на существование значения - тогда как получается так, что результатом этого цикла получается отсортированный список одинаковых чисел? В любом случае, спасибо за ответ, буду тоже думать...
@someonesomeone8668
@someonesomeone8668 5 лет назад
@@ПростоАмби Ну так когда stat[a[i]] не присвоено, else его присваевает к 1. Поэтому всё и работает.
@ПростоАмби
@ПростоАмби 5 лет назад
@@someonesomeone8668 Всё, врубился, спасибо большое!
@lekca216
@lekca216 5 лет назад
Изначально "stat" пустой, а сгенерированные числа из массива "a" мы используем как индексы для "stat", при первой встрече каждого индекса в него записывается единица (через "else"), при каждой следующей встрече значение увеличивается на 1, "if" просто проверяет на существование, можно было сразу обнулить все значения до "10" и без проверки делать stat++, но было бы не так интересно) а более развернуто "if" можно написать как if(stat == true) { stat++ } else { stat = 1 }, прикольная штука. В "if" вообще все что хочешь можно закинуть, и значения вроде "0" "null" "NaN" "false" "undefined" или пустая строка "" он воспримет как ложь и выполнится "else", все остальные значения, включая дробные и отрицательные числа воспримет как истину и выполнит свой блок, поэтому пока stat пустой он считается ложью, а когда в него закинули единицу он стал истиной) P.S. видел, что ответ уже есть, но хотел дать свой ответ, может кому-то понятнее покажется)
@АлександрМелянюк-ц9ю
Блин, как же круто Человек объясняет и учит! Это я про все видео! Спасибо!
@rickgrimes7734
@rickgrimes7734 5 лет назад
а где новые видео?проверяю каждый день колокольчик((
@vozay
@vozay 5 лет назад
За столько лет не решили эту проблему!!!
@faust2134
@faust2134 5 лет назад
Проблемы нет
@Евгений-х4л2щ
@Евгений-х4л2щ 5 лет назад
Это не проблема, это элементарные законы математики
@ArmxakerMkrtchyan
@ArmxakerMkrtchyan 4 года назад
:) сделайте размер фонта большим
@BlackTrade704
@BlackTrade704 2 месяца назад
Я ничего не понял
@Давид-п8и
@Давид-п8и 5 лет назад
👍👍👍
@yakut54
@yakut54 5 лет назад
лайкос!
@redcrown5789
@redcrown5789 4 года назад
На зеро больше не ставим=)
@drak0an
@drak0an 4 года назад
ВГ/АМ
@РоманМельничук-ш4м
крууто
@viacheslavgava4321
@viacheslavgava4321 5 лет назад
Дякую!
@ptruskovsky
@ptruskovsky 5 лет назад
Ну такое распределение у Math.Random(). Не совсем ясно в чем претензия к этой функции. Не нравится эта, возьмите другую.
@k.marchenko
@k.marchenko 5 лет назад
Он и говорит, что нужно брать другую
@oleg_maksiuta
@oleg_maksiuta 5 лет назад
С Math.random() как раз всё в порядке. Просто нужно округлять числа, используя Math.floor(), а не Math.round()
@logius84
@logius84 4 года назад
понятно рассказали, благодарю
@purel2449
@purel2449 5 лет назад
public static boolean chance(int chance) { rnd =(int)(Math.random *100); return chance >= 1 && (chance > 99 || rnd + 1
@timur.shhhhh
@timur.shhhhh Год назад
Это можно доказать математически. х є [0; 1) / [0.000; 0.999]. Если умножить такое число на 3 => [0.000; 2.997]. Также важен факт, что Math.round() округляет 0.500 => 1/ 1.499 => 1. И применив комбинаторику и теорию вероятности => всего вариантов 2000, подходящих для первого - 500, для 2 - 1000, для 3 - 500, то есть Р(1) = 0.25, Р(2) = 0.5, Р(3) = 0.25. То есть шанс чтобы выпало 2 такой-же, как и 1 или 2. Можно добавить, что первое + последнее === любому другому. Лучше пользоваться Math.floor(Math.random() * ( n +1)) //n = 3 //1, 2, 3
@delusio5638
@delusio5638 Год назад
иди нах с математикой, комп придумали чтоб меньше думать
Далее
БАГ ЕЩЕ РАБОТАЕТ?
00:26
Просмотров 123 тыс.
TrueJS 32. AddEventListener - события
25:37
Просмотров 36 тыс.
Убираем маты. JavaScript
11:12
Просмотров 9 тыс.