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

แชร์
ฝัง
  • เผยแพร่เมื่อ 15 พ.ย. 2024
  • Курс JS: js.itgid.info
    Курс вестки: html.itgid.info
    Интернет магазин на Node: node.itgid.info
    Плейлист: goo.gl/63osiv
    Телеграм: t.me/jsrules
    Мои курсы: itgid.info
    Делаем статистику массива и изучаем Math.random в JavaScript

ความคิดเห็น • 80

  • @uncle-xxi
    @uncle-xxi 5 ปีที่แล้ว +31

    Ошибка в том, что 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 8 หลายเดือนก่อน

      абсолютно верно. С первых секунд ролика, как только увидел этот график, так сразу понял ошибку)

    • @SerzhNesteruk
      @SerzhNesteruk 7 หลายเดือนก่อน

      Согласен. Но кроме этого меня ещё смущает постоянное использование "грязных функций". Поддержка проекта даже среднего размера, где ни одна функция не является "чистой", - это просто адище. Такой код невозможно покрыть юнит-тестами, крайне трудно отлаживать, расширять и рефакторить. Это действительно ужас и боль. 😰

  • @alegerov9825
    @alegerov9825 5 ปีที่แล้ว +28

    Random умножать на 10.99, вместо Round использовать Floor. Round отсекает у 0 и 10 половину поля значений, поэтому и получается их частота вдвое ниже остальных.

    • @faust2134
      @faust2134 5 ปีที่แล้ว +4

      Именно. Придумали проблему из ничего

    • @leksanders8908
      @leksanders8908 5 ปีที่แล้ว

      @@igormikailov4200 =)))))))

  • @magik6831
    @magik6831 5 ปีที่แล้ว +23

    Случайно упал взгляд на время и 7 утра) Этот человек любит свою работу, однозначно! Дай Бог Вам здоровья!)))

    • @magik6831
      @magik6831 3 ปีที่แล้ว

      @Ramon Gustavo wow, I didn't know, thanks))

  • @faust2134
    @faust2134 5 ปีที่แล้ว +17

    напишите это в консоли, внимание на результат.
    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 ปีที่แล้ว +26

      Об"ясню подробнее, что бы все поняли....
      Каким образом у нас получаются цифры от 1 - 9? Округление. К примеру выпадают числа: 0.5 - будет 1. 1.4999 - будет 1. Вполне нормальный диапазон [0.5, 1.5).
      Ноль получается всё так же, округление. 0.4999..... - будет 0. А всё выше - будет 1. Итого диапазон для нуля у нас [0, 0.5)
      Для 10 это работает так же
      Вот и об"яснение "сломанного рандома"

    • @alexredcross
      @alexredcross 5 ปีที่แล้ว

      Спасибо) реально думал что вся проблема в математическом округлении)

    • @виртуоз_ру
      @виртуоз_ру 5 ปีที่แล้ว +2

      @@faust2134 У тебя слово выводится с ошибкой, надо так: объяснение

    • @ДмитрийХорькин
      @ДмитрийХорькин 5 ปีที่แล้ว +2

      Да уж, прикинь, об этом этот чувак ещё и ролик загрузил, и говорит, что Math.random некорректен. Действительно, если бы человек знал как работает Math.floor, то смог бы понять, что по статистике Math.random работает корректно и выдаёт "хорошее" равномерное распределение от 0 до 1. Тупо тер вер надо учить.

  • @ОксанаХарченко-д9г
    @ОксанаХарченко-д9г 2 ปีที่แล้ว +1

    спасибо, за хорошее объяснение, но в конце я ожидала вариант решения в вашей подаче

  • @H336-p1v
    @H336-p1v 5 ปีที่แล้ว +11

    *Как насчёт увеличить шрифт?*
    А то с телефона не шибко удобно смотреть :

    • @liskorsbi
      @liskorsbi 5 ปีที่แล้ว

      Я с телефона смотрю и все норм, мб у тебя телефон слишком маленький?

    • @H336-p1v
      @H336-p1v 5 ปีที่แล้ว +7

      владислав Ковалев Телефон у меня.. да,маленький, не спорю.
      Но всё же удобнее с большим шрифтом.

    • @АйПад-Два
      @АйПад-Два 4 ปีที่แล้ว

      Поддерживаю,у меня не маленький телефон(A50) и все равно неудобно

  • @slapiinf518
    @slapiinf518 5 ปีที่แล้ว +1

    Добрый день, Александр.
    Не могли бы Вы записать урок, как сделать QUIZ. И по завершению отправить ответы на почту.
    Спасибо.

  • @freshmotion5401
    @freshmotion5401 5 ปีที่แล้ว +1

    Спасибо за уроки.и помощь в понимании JavaScript.

  • @justandrew4275
    @justandrew4275 5 ปีที่แล้ว +1

    Здравствуйте, Александр, нигде не могу найти, как зарегистрироваться на вашем сайте ддя прохождения бесплатного курса. Нашел только, как залогиниться, но не зарегистрироваться. Или же курс рассчитан на тех, кто уже купил хоть 1?

  • @uracan7872
    @uracan7872 5 ปีที่แล้ว +3

    Спасибо большое , отличный пример !!

  • @nun8930
    @nun8930 5 ปีที่แล้ว +2

    Так а как правильно генерировать через Math.floor?

  • @АлександрМелянюк-ц9ю
    @АлександрМелянюк-ц9ю 5 ปีที่แล้ว +3

    Блин, как же круто Человек объясняет и учит! Это я про все видео! Спасибо!

  • @watsontv5834
    @watsontv5834 5 ปีที่แล้ว +1

    Спасибо за Ваши уроки. Снимите пожалуйста видео по парсингу на node.js

  • @vozay
    @vozay 5 ปีที่แล้ว +5

    Генерировать на два числа больше необходимого и отбрасывать крайние значения.

  • @slovesnov
    @slovesnov 3 ปีที่แล้ว

    x=10*Math.random() - это случайное число 0

  • @korop5851
    @korop5851 5 ปีที่แล้ว +3

    Если округлить 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 9 หลายเดือนก่อน

      искал этот коммент

  • @divocean4085
    @divocean4085 5 ปีที่แล้ว +1

    Более того, псевдорандомность math.random заключается ещё и в том, что одинаковые числа часто выпадают подряд друг за другом. Например 7, 7, 8, 8, 8, 6, 6 и т.д, что происходит из-за округления дробной части.

  • @delayLama_ru
    @delayLama_ru 5 ปีที่แล้ว +4

    Так, а как правильно то генератор чисел делать? Чтоб поровну чисел получалось..

    • @k.marchenko
      @k.marchenko 5 ปีที่แล้ว

      Он приводил сайт в видео. Там 3 способа

    • @oleg_maksiuta
      @oleg_maksiuta 5 ปีที่แล้ว

      Самый простой способ - делать тоже самое, только для округления использовать Math.floor вместо Math.round. В таком случае будут равномерно сгенерированны числа от минимального (включительно) до максимального (не включительно)

  • @hachiko489
    @hachiko489 5 ปีที่แล้ว +2

    *Расскажите о "self" в JavaScript*

    • @luricsapi3070
      @luricsapi3070 5 ปีที่แล้ว

      Self - это по сути название переменной, которой присваивается this.
      Место self может быть любое название переменной , с присваиванием переменной связанно использование основного контекста внутри вложенной функции.
      Если нужны примеры, могу объяснить на пальцах

  • @andreychekan9908
    @andreychekan9908 3 ปีที่แล้ว +1

    В діапазоні від 0 до 10 включно потрібно так Math.floor((10*Math.random())+1); Юзабельніть Round в іншому (на відео все видно), а от Math.ceil((11*Math.random())-1) більш природно показує результат на графіках.

  • @назаркоцюба-э2п
    @назаркоцюба-э2п 5 ปีที่แล้ว +1

    круто спасибо . Больше таких видосов

  • @denisoleksyuk5346
    @denisoleksyuk5346 3 ปีที่แล้ว

    так а почему так происходит? Я пропустил объяснение?

  • @holodina
    @holodina 3 หลายเดือนก่อน

    Мы можем генерировать число в диапозоне и всё, никакой проблемы.
    ~~(Math.random() * (max - min + 1)) + min;

  • @utlookworld5784
    @utlookworld5784 3 ปีที่แล้ว

    Задачи по массивами обычно решаю круглосуточно..
    Если мне какая-то задачка попадется, то я даже уснуть не могу - она у меня в голове крутится и крутится.
    Пока в голове решение не созреет, не могу заснуть :(

  • @denismerigold486
    @denismerigold486 5 ปีที่แล้ว +1

    please! сделайте курс по python

  • @Юрий-р9в8д
    @Юрий-р9в8д 5 ปีที่แล้ว +1

    ребята помогите решить пожалуйста
    На вход подается фраза на русском языке, содержащая числительное. Например, "Я хочу квартиру за 10.5 миллионов" или "Мне нравится когда моя машина, стоимостью сотку штук баксов, мелькает по телевизору". Необходимо выделить числительное в форме натурального числа и вернуть.

    • @lekca216
      @lekca216 5 ปีที่แล้ว

      А что тут писать, всего-то указать соответствие для всех возможных слов, обозначающих числа, во всех возможных формах, типа "миллион" && "миллионов"&& "миллиона" && "лимон" && "лимонов" && "лимона" && "лям" && "лямов" && "ляма" && "мульт" && "мульта" && "мультов", ставишь в соответствие к умножению на 1,000,000 и перебираешь строки, аналогично со словами вроде "сотку" или "штук", само собой не забудь поставить проверки контекста, ведь "штук" может означать 1, а может и 1000, да и не каждый лимон должен стать миллионом, помни об этом)) И да прибудет с тобой терпение)

  • @Sergey-wo3vu
    @Sergey-wo3vu 2 ปีที่แล้ว

    Если знать математику и тервер ничего удивительного в работе рандомных генераторов в ЯП нет. Они работают, как и должны работать. Но многие даже не подозревают, что нельзя их использовать, к примеру, для выбора победителя в розыгрышах.

  • @DrZlad
    @DrZlad 5 ปีที่แล้ว +3

    Спасибо огромное за урок.
    Но: момент настройки графика, сорвал последовательность восприятия самой сути урока, я тут же потерял фокус восприятия, и перефокусировался на настройки графика- и получился урок: физики+ рисования, вроде и связь есть, но всё о разном)))
    Успехов Вам!!!

  • @ПростоАмби
    @ПростоАмби 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 ปีที่แล้ว +1

      Если вкратце, то браузер пытается опустить код в 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 ปีที่แล้ว +1

      @@ПростоАмби Ну так когда stat[a[i]] не присвоено, else его присваевает к 1. Поэтому всё и работает.

    • @ПростоАмби
      @ПростоАмби 5 ปีที่แล้ว

      @@someonesomeone8668 Всё, врубился, спасибо большое!

    • @lekca216
      @lekca216 5 ปีที่แล้ว +2

      Изначально "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. видел, что ответ уже есть, но хотел дать свой ответ, может кому-то понятнее покажется)

  • @uncle-xxi
    @uncle-xxi 5 ปีที่แล้ว +1

    зачем перебор, сразу в генераторе стату надо считать было :)

  • @rickgrimes7734
    @rickgrimes7734 5 ปีที่แล้ว

    а где новые видео?проверяю каждый день колокольчик((

  • @ДмитрийНалетов-ч2т
    @ДмитрийНалетов-ч2т 4 ปีที่แล้ว +1

    Неправильное округление. Диапазон значений для 1 и 10 вдвое короче. Округляйте вниз.

  • @Давид-п8и
    @Давид-п8и 5 ปีที่แล้ว +1

    👍👍👍

  • @vozay
    @vozay 5 ปีที่แล้ว +1

    За столько лет не решили эту проблему!!!

    • @faust2134
      @faust2134 5 ปีที่แล้ว +3

      Проблемы нет

    • @Евгений-х4л2щ
      @Евгений-х4л2щ 5 ปีที่แล้ว

      Это не проблема, это элементарные законы математики

  • @dmitryn.9765
    @dmitryn.9765 3 ปีที่แล้ว

    вся вышеописанная программа в вашей православной консоли с одной строки
    let stat=[]; for( let i=0; i

  • @ArmxakerMkrtchyan
    @ArmxakerMkrtchyan 4 ปีที่แล้ว

    :) сделайте размер фонта большим

  • @purel2449
    @purel2449 5 ปีที่แล้ว +1

    yesli nujen algoritm randoma to mojesh ispolzuvat eto

  • @yakut54
    @yakut54 5 ปีที่แล้ว +1

    лайкос!

  • @logius84
    @logius84 4 ปีที่แล้ว

    понятно рассказали, благодарю

  • @redcrown5789
    @redcrown5789 5 ปีที่แล้ว

    На зеро больше не ставим=)

  • @BlackTrade704
    @BlackTrade704 4 หลายเดือนก่อน

    Я ничего не понял

  • @ptruskovsky
    @ptruskovsky 5 ปีที่แล้ว

    Ну такое распределение у Math.Random(). Не совсем ясно в чем претензия к этой функции. Не нравится эта, возьмите другую.

    • @k.marchenko
      @k.marchenko 5 ปีที่แล้ว

      Он и говорит, что нужно брать другую

    • @oleg_maksiuta
      @oleg_maksiuta 5 ปีที่แล้ว +3

      С Math.random() как раз всё в порядке. Просто нужно округлять числа, используя Math.floor(), а не Math.round()

  • @viacheslavgava4321
    @viacheslavgava4321 5 ปีที่แล้ว

    Дякую!

  • @РоманМельничук-ш4м
    @РоманМельничук-ш4м 5 ปีที่แล้ว

    крууто

  • @olegBilyi-n4j
    @olegBilyi-n4j 2 ปีที่แล้ว

    Дякую

  • @drak0an
    @drak0an 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 ปีที่แล้ว

      иди нах с математикой, комп придумали чтоб меньше думать