Как задать диапазон рандомизации rand()?

Проблема: не умею задавать диапазон рандомизации от 2003 к 2020.
Мой код:

struct Date
{
    int day = rand() % 29;
    int month = rand() % 12;
    int year = rand() % 2020+2003;
    void Print()
    {
        cout << "Date of B:" << day << "." << month << "." << year << endl;
    }
};

Но у меня выходит какая-то каша, помогите сделать так, чтобы дата рандомилась, например, от 2003 года к 2020 году.


Ответы (2 шт):

Автор решения: Harry

Только тогда уж рандомизируйте и месяцы-дни правильно :)

int month = rand() % 12 + 1; // Январь - 1...
int year = rand() % 18 + 2003;  // От 2003 до 2003 + 17
const int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int D = md[month-1];
if (month == 2 && year%4 == 0) ++D;

int day = rand() % D + 1;

Хотя через юлианскую дату и нормальный <random> было бы равномернее; а так, например, будет небольшой перекос - поскольку в феврале меньше дней, а на них будет приходиться то же количество выпаданий, что и на любой другой месяц...

→ Ссылка
Автор решения: Vladimir Gamalyan

В C++20 (равномерное распределение по дням между from/to включительно):

#include <iostream>
#include <chrono>
#include <random>

using namespace std::chrono;

int main() {
  auto from = sys_days{January/1/2003};
  auto to = sys_days{December/31/2020};

  std::random_device dev;
  std::mt19937 rng(dev());
  std::uniform_int_distribution<std::mt19937::result_type> dist(0, (to - from).count());

  year_month_day random_date = from + days{dist(rng)};

  std::cout << static_cast<int>(random_date.year()) << std::endl;
  std::cout << static_cast<unsigned>(random_date.month()) << std::endl;
  std::cout << static_cast<unsigned>(random_date.day()) << std::endl;
}

Рабочий пример

→ Ссылка