Рандомні числа

Доволі часто виникає потреба згенерувати рандомне число. Для прикладу, якщо ви пишете програму яка імітує випадання грального кубика. Або вам потрібні довільні числа щоб заповнити масив.

У мові програмування рандомні числа поділяють на два види:

Псевдорандомними називають ті числа які програма обирає самостійно але з кожним запуском вони повторюються.

Щоб згенерувати рандомне число (на початку воно буде псевдорандомним) варто скористатися функцією Вона генерує ціле додатне число.

Розглянемо наступну програму. В ній змінна два рази отримує довільне рандомне число. Для демонстрації, що ці числа є різними ми значення цієї змінної двічі виводимо.

    
            #include <iostream>
            int main()
            {
                int a;

                a = rand();
                std::cout << a << std::endl;
                a = rand();
                std::cout << a << std::endl;

                return 0;
            }
        
    

Але при кожному запуску програми ці числа будуть однаковими. Тому, їх називають псевдорандомними.

Цього буває достатньо щоб заповнити масив і перевірити працездатність програми але в реальності цього занадто мало.

Для того щоб мати можливість псевдорандомні числа можна використовувати функцію та вказувати в якості її аргумента довільне ціле додатне число. Цю функцію варто записувати лише один раз. Краще за все на початку програми або безпосередньо перед першим використанням

    
            #include <iostream>
            int main()
            {
                srand(1);
                int a;

                a = rand();
                std::cout << a << std::endl;
                a = rand();
                std::cout << a << std::endl;

                return 0;
            }
        
    

Міняючи число в якості аргумента функції ви будете отримувати різні псевдорандомні числа. Але при запуску програми з одним і тим же числом ви знову ж таки будете мати однакові результати.

Для того щоб гарантовано отримувати кожного разу новий результат вам варто підключити бібліотеку або Також в якості аргументу функції варто вказати або

    
            #include <iostream>
            #include <ctime>
            int main()
            {
                srand(time(0));
                int a;

                a = rand();
                std::cout << a << std::endl;
                a = rand();
                std::cout << a << std::endl;

                return 0;
            }
        
    

Коли в якості аргумента ви ставите то на справді ви вказуєте кількість секунд, що пройшло від до моменту запуску програми. Тому, ви і отримаєте різні результати.

Як помітно, результати бувають доволі різними. Якщо потрібно обмежити діапазон чисел, то можна зробити так:


        rand() % max;
        

Де «max» це число ДО якого ви можете отримати рандомне число. В такій ситуації ви будете мати діапазон чисел від «0» до «max - 1».

Звісно, щоб отримати включно з максимальним числом ви можете вказувати на одиницю більше число. Тобто, коли хочете отримати діапазон чисел то можна вказати: Або:

Отже, щоб отримати діапазон чисел ВКЛЮЧНО з максимальним потрібно до максимального числа додати При цьому, якщо ви хочете додавати її окремо, то цей запис має бути обов’язково у дужках.

    
            #include <iostream>
            #include <ctime>
            int main()
            {
                srand(time(0));
                int a;
                //числа від «0» до «14» включно
                a = rand() % 15;

                std::cout << a << std::endl;

                return 0;
            }
        
    

Якщо ж ви хочете отримати числа від якогось конкретного найменшого (вказати самостійно мінімальне число), то вам варто використати метод:


        rand() % (max – min) + min;
        

І відповідно, якщо ви хочете мати включно з максимальним числом, то у дужках ще потрібно додати (або максимальне число враховувати разом з цією одиницею):


        rand() % (max – min + 1) + min;
        

Наприклад:

    
            #include <iostream>
            #include <ctime>
            int main()
            {
                srand(time(0));
                int a;
                //числа від «15» до «25» включно
                a = rand() % (25 – 15 + 1) + 15;
                std::cout << a << std::endl;

                int max = 60, min = 50;
                //числа від «50» до «60» включно
                a = rand() % (max – min + 1) + min;
                std::cout << a << std::endl;

                return 0;
            }
        
    

Давайте розберемося як це працює. Припустимо, ми хочемо отримати діапазон чисел Тоді, наший запис буде таким: Якщо ж до цього запису ми допишемо (тобто, отримаємо то і діапазон чисел збільшиться. Будемо мати і Тобто, максимальним числом вже буде Це ж в свою чергу буде дуже сильно збивати з пантелику, адже в якості максимального числа ми очікували

Відповідно, щоб уникнути подібних ситуацій ми зменшуємо максимальне числа, а потім повертаємо його до попереднього значення.

Дуже часто отримання рандомних чисел виносять в окрему функцію:

    
            #include <iostream>
            #include <ctime>

            //оскільки часто в якості мінімально числа
            //беруть "0", то ми можемо взяти його
            //зі значенням за замовчуванням.

            //якщо вам не лінь кожного разу
            //передавати два аргументи функції,
            //то можете скористатися таким записом:
            //int randI(int min, int max)
            int randI(int max, int min = 0)
            {
                return rand() % (max - min + 1) + min;
            }

            int main()
            {
                //зверніть увагу. Функцію "srand"
                //ми вказуємо в головній програмі
                srand(time(0));

                int a;
                //діапазон від 0 до 10
                a = randI(10);
                std::cout << a << std::endl;

                //діапазон від 20 до 30
                a = randI(30, 20);
                std::cout << a << std::endl;

                return 0;
            }
        
    

Якщо ви хочете отримати дробові рандомні числа, то вам доведеться написати власну функцію. Відразу зауважимо, що таким числам варто вказувати кількість цифр після крапки (вказувати їх точність).

    
            #include <iostream>
            #include <cmath> //для використання функції pow
            #include <ctime>

            //створюємо функцію яка повертає
            //рандомне дробове число
            //із заданою кількістю цифр після крапки
            //(із заданою точністю)

            //функція отримує 3 аргументи:
            //min - найменше число
            //max - найбільше число
            //precision - точність, кількість знаків після коми.
            double randF(double min, double max, int precision)
            {
                double value;

                //отримуємо довільне ціле число з точністю precision
                value = rand() % (int)pow(10, precision);

                //отримуємо число з крапкою
                value = (value / pow(10, precision)) * (max - min) + min;

                return value;
            }

            int main()
            {
                double number;

                srand(time(0));

                //Отримуємо число в межах від "0"
                //до "2" з точністю "3" знаки після коми
                number = randF(0, 2, 3);
                std::cout << "number = " << number << std::endl;

                return 0;
            }
        
    

Як вже було сказано раніше рандомні числа дуже зручно використовувати для заповнення масивів. Наприклад:

    
            #include <iostream>
            #include <ctime>

            int main()
            {
                srand(time(0));
                int mas[2][3];

                for(int i = 0; i < 2; i++)
                {
                    for(int j = 0; j < 3; j++)
                    {
                        //діапазон чисел буде від "1" до "20" включно
                        mas[i][j] = rand() % 20 + 1;
                    }
                }

                for(int i = 0; i < 2; i++)
                {
                    for(int j = 0; j < 3; j++)
                    {
                        std::cout << mas[i][j] << " ";
                    }
                    std::cout << std::endl;
                }

                return 0;
            }