Генератор случайных чисел

203
19 декабря 2016, 19:45

Не могу понять как заставить генератор случайных чисел давать дробные значения. Пробовал сделать так. A = rand() % 158.691+(-1.235);

не получилось. Интервал от -1.235 и 157.456.

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
    int N,M;
    int max = 157456, min = -1235;
    cout << "Enter size of matrix A:N " << endl;
    cin >> M;
    cout << "Enter size of matrix A:M " << endl;
    cin >> N;
    cout << "Creating matrix A:" << endl;
    // Создаётся матрица A
    float **A = new float* [M];
    srand(time(NULL));
    int i = 0;
    do {
        A[i] = new float [N];
        i++;
    }
    while(i<N);
    int j = 0;
    do {
        do {
            float float k = rand();
            k = k%(max - min) + min;
            //double результат = (double)число / (double)1000;
            A[i][j] = (float)k/(float)1000;;
            cout << setw(10) << A[i][j];
            i++;
        }
        while(i<M);
        j++;
        cout << endl;
    } 
    while(j<N);
    cout << endl << endl;
 // Освобождение памяти
    for (int i = 0; i < N; i ++) delete [] A[i];
    delete [] A;
    system("pause");
    return 0;
}
Answer 1

На самом деле всё просто.

// Генерирует случайное действительное число от 0 до 1
(double)(rand())/RAND_MAX 
// Генерирует случайное действительное число от 0 до N
(double)(rand())/RAND_MAX * N

Вот пример:

#include <stdlib.h>
#include <time.h>
#include <iostream>
using namespace std;
// Функция, генерирующая случайное действительное число от min до max
double random(double min, double max)
{
    return (double)(rand())/RAND_MAX*(max - min) + min;
}
int main() 
{
    srand((unsigned int)time(0));
    cout << random(-1.235, 157.456) << endl;
    return 0;
}

Здесь проверка.

Answer 2

Все вышеперечисленные способы сводятся примерно к одной формуле:

res = min + (max - min) / RAND_MAX * rand();

Тут могут быть проблемы, если число значащих цифр в RAND_MAX меньше, чем в мантиссе результирующего типа. Такое может случиться, даже если res имеет тип float (RAND_MAX далеко не всегда равен INT_MAX, а может быть намного меньше). Возможно, что и в противном случае, с распеределением что-то будет не так, не могу сказать точно.

Поэтому, не может не радовать, что разработчики стандарта позаботились о нас и добавили в стандартную библиотеку новый модуль <random>.

#include <iostream>
#include <random>
#include <chrono>
int main() {
  const double from = -1.235;
  const double to = 157.456;
  using namespace std::chrono;
  std::default_random_engine engine(
      system_clock::to_time_t(system_clock::now()));
  std::uniform_real_distribution<> distr(from, to);
  auto gen_number = [&engine, &distr] () { return distr(engine); };
  for (int i = 0; i < 50; ++i) {
    std::cout << gen_number() << std::endl;
  }
}
Answer 3

Вот так работает?

double мин = -1.235;
double макс = 157.456;
int мин__ = (int)(мин*1000);
int макс__ = (int)(макс*1000);
long long число = rand(); 
число =  число%(макс__ - мин__) + мин__;
double результат = (double)число / (double)1000;
std::cout << "\nрезультат=" << результат;

Проверка:

for(int i = 0; i < 1000000; i++)
{
int min = -1235;
int max = 157456;
    //
srand(наносекунды);
long long D = rand(); 
D =  D%(max - min) + min;
double result = (double)D / (double)1000;
if(result < -1.235)
{
std::cout << "\nменьше=" << result;
}
if(result > 157.456)
{
std::cout << "\nбольше=" << result;
}
}

@ Вот ваш код.

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;


int main(){
    int N,M;
    int max = 157456, min = -1235;
    cout << "Enter size of matrix A:N " << endl;
    cin >> M;
    cout << "Enter size of matrix A:M " << endl;
    cin >> N;
    cout << "Creating matrix A:" << endl;
    // Создаётся матрица A
    float **A = new float* [M];
    srand(time(NULL));
    int i = 0;
    do {
        A[i] = new float [N];
        i++;
    }
    while(i<M);
    int j = 0;
// Здесь обнулить счётчик i
i = 0;
    do {
        do {
            int k = rand();
            k = k%(max - min) + min;
            //double результат = (double)число / (double)1000;
            A[i][j] = (float)k/(float)1000;;
            cout << setw(10) << A[i][j];
            i++;
        }
        while(i<M);
// Здесь еще раз обнулить счётчик i
i=0;
        j++;
        cout << endl;
    } 
    while(j<N);
    cout << endl << endl;
 // Освобождение памяти
    for (int i = 0; i < M; i ++) delete [] A[i];
    delete [] A;
    system("pause");
}

// обновление семя раз в секунду srand(секунды);

// обновление семя 1000 раз в секунду srand(миллисекунды);

// обновление семя 1000000 раз в секунду srand(микросекунды);

// обновление семя 1000000000 раз в секунду srand(наносекунды);

Вид пикселей:

Секунды:

Миллисекунды:

Микросекунды:

Наносекунды:

Answer 4
srand(time(NULL));
double a = (double)(rand()%10000);

ну и соответственно добавьте слагаемые-множители для соблюдения требуемого диапазона

Answer 5

Не уверен что с цифрами правильно высчитал, так что если подойдёт такое решение сами пере проверти, что бы он нужные вам числа выдавал.

#include <iostream>
#include <ctime>
#include <cstdlib>
int main()
{
    srand(time(0));
    double result;
    int celoe = 0, drobi = 0, znak = 0;
    char buff[10];
    znak = rand() % 2; // 1
    buff[0] = znak ? ' ' : '-';
    if (buff[0] == '-') {  // 2
        celoe = rand() % 2; // Генерирует от 0 до 1
        drobi = rand() % 236; // Генерирует от 0 до 235
        sprintf(&buff[1], "%d.%d", celoe, drobi); // 4
    } else {  //3
        celoe = rand() % 158; // Генерирует от 0 до 157
        drobi = rand() % 457; // Генерирует от 0 до 456
        sprintf(buff, "%d.%d", celoe, drobi); // 4
    }
    result = atof(buff);  // 5
    std::cout << result << "\n";  // 6
    system("pause");
    return 0;
}
  1. Генерируем число от 0 до 1 которое будет определять знак будущего дробного числа.
  2. Проверяем если у нас число будет отрицательным то генерируем значения из диапазона чисел которые могут входить в отрицательное дробное число.
  3. Ну а если число положительное то для положительного генерируем числа из нужного вам диапазона.
  4. Здесь мы создаём из получившихся чисел строку с дробным числом.
  5. Преобразуем строку с числом в число double
  6. Выводим результат

P.S. Народ если есть простой способ генерировать дробные значения то отпишитесь, может зря я такую муть городил на ночь глядя ))

А можно вынести в отдельную функцию и при вызове функции передавать нужные диапазоны и получать результат.

#include <iostream>
#include <ctime>
#include <cstdlib>
double generate(int min_celoe, int min_drobi, int max_celoe, int max_drobi)
{
    double result;
    int celoe = 0, drobi = 0, znak = 0;
    char buff[10];
    znak = rand() % 2;
    buff[0] = znak ? ' ' : '-';
    if (buff[0] == '-') {
        celoe = rand() % (min_celoe + 1);
        drobi = rand() % (min_drobi + 1);
        sprintf(&buff[1], "%d.%d", celoe, drobi);
    } else {
        celoe = rand() % (max_celoe + 1);
        drobi = rand() % (max_drobi + 1);
        sprintf(buff, "%d.%d", celoe, drobi);
    }
    result = atof(buff);
    return result;
}
int main()
{
    srand(time(0));
    double results[100];
    for (int i = 0; i < 100; i++) {
        results[i] = generate(1, 235, 157, 456);
        std::cout << results[i] << "\n";
    }
    system("pause");
    return 0;
}
READ ALSO
Стоит ли использовать Qt C++?

Стоит ли использовать Qt C++?

Всем привет, около месяца пишу на C++ и вот появилась мысль попробовать Qt, тем более он кроссплатформенный

244
Как указать связи между указателями и исходными данными?

Как указать связи между указателями и исходными данными?

При сериализации в boost::serialization можно записать вектор std::vector<int> base;

261