Как увеличить диапазон функции rand

246
04 февраля 2018, 01:36

Всем привет. Пытаюсь сделать, чтобы выдавало большое случайное число. Пытаюсь сделать так:

__int64 p= 489133282872437279;
__int64 s = rand() % p + 1;

Но почему-то rand выдает маленькие значения. Это потому, что RAND_MAX = 32767. Как его можно увеличить?

Answer 1

Конечно лучше воспользоваться какой-нибудь библиотекой, но если это учебная программа то можно и самому реализовать.

В основе rand() лежит линейный конгруэнтный метод. Реализация которого примерно такая:

#define RAND_MAX 32767 
static unsigned long int next = 1;

int rand(void)
{
  next = next * 1103515245 + 12345;
  return (unsigned int)(next/65536) % (RAND_MAX + 1);
}
void srand(unsigned int seed)
{
  next = seed;
}

Как можно видеть отсюда, поменять диапазон очень легко: нужно RAND_MAX заменить на свое число и поменять int на long long int.

Но rand() достаточно "туповат" если реализовывать то лучше взять вихрь мерсена у него лучше статистическая устойчивость и он достаточно прост в реализации.

Answer 2

Когда-то давно я писал вот такое на основе Кнутового "Искусства программирования":

class Random
{
public:
    typedef int RandomValue;
    Random& operator = (int seed) { X = seed; return *this; }
    Random(int seed = 1):X(seed){};
    int operator()(int seed = 0)
    {
        const int MM = 2147483647;
        const int AA =      48271;
        const int QQ =      44488;
        const int RR =       3399;
        if (seed != 0) X = seed;
        X = AA*(X%QQ)-RR*(X/QQ);
        if (X < 0) X += MM;
        return X-1;
    }
    int operator()(int min, int max)
    {
        return (*this)()%(max-min) + min;
    }
private:
    int X;
};
class Random64
{
typedef unsigned long long uint64;
public:
    typedef uint64 RandomValue;
    Random64& operator = (uint64 seed) { X = seed; return *this; }
    Random64(uint64 seed = 0):X(seed){};
    uint64 operator()(uint64 seed = uint64(-1))
    {
        const uint64 a = 3202034522624059733ULL;
        const uint64 c =                   1ULL;
        if (seed != uint64(-1)) X = seed;
        uint64 Y = a * X + c;
        X = a * Y + c;
        Y = (Y&0xFFFFFFFF00000000ULL) | (X >> 32);
        return Y;
    }
    uint64 operator()(uint64 min, uint64 max)
    {
        return (*this)()%(max-min) + min;
    }
private:
    uint64 X;
};

Думаю, как пользовать, понятно?

Answer 3

Вы можете :

  1. Воспользоваться сторонней библиотекой: http://www.boost.org/doc/libs/1_49_0/doc/html/boost_random.html

  2. Сделать нечто подобное: Рандомом получить a; Рандомом получить b; И сделать некую сумму: a * (RAND_MAX + 1) + b;

READ ALSO
SFML под Android - ошибка установки

SFML под Android - ошибка установки

Пытаюсь установить SFML под Android по этой доке: https://githubcom/SFML/SFML/wiki/Tutorial:-Building-SFML-for-Android

281
Как дебажить DLL

Как дебажить DLL

Есть DLL на C++Её методы могут быть вызваны как другими DLL так и исполняемыми файлами или скриптом

346
std::wstring присваивание == копирование

std::wstring присваивание == копирование

Если кратко описать вопрос то будет примерно так:

212
Toolbar группирует иконки

Toolbar группирует иконки

Добрый день добавил 3 иконки в toolbar он сгруппировал их в ментоесть 1 иконка есть другая кионка группировки

456