Генерация случайных чисел, не используя битовые операции

Объявление оператора < < () неверно. Для двоичной версии op < < вам не нужно объявлять второй параметр - предполагается, что он будет this, если op < < является функцией-членом класса:

virtual ostream& operator<<(ostream& stream) = 0;

Более того, как упоминалось другими, операторы вставки потока должны быть глобальными функциями. Создание функций-членов просто не сработает.

Также не то, что не связано с вашим вопросом, но проблема, тем не менее. В исходной реализации вы передали абстрактный объект базового класса по значению, а не по ссылке или по указателю. Когда вы делаете это, вы «режете объект». Я уверен, что вы намеревались передать функции указатель базового класса на полиморфный тип, а затем полиморфно вызывать методы вызова функции. Например, вы пытались сделать что-то похожее на это:

#include 
#include 
#include 
using namespace std;

class Base 
{
public:
    virtual void dump() 
    {
        cout << "Base";
    };
};

class Der : public Base
{
public:
    void dump()
    {
        cout << "Der";
    };
};

void DumpIt(Base b)
{
    b.dump();
}


int main() 
{
    Der obj;
    DumpIt(obj);
    return 0;

}

... и ожидали, что на выходе будет «Der», но на самом деле на выходе получается «Base» из-за Object Slicing . Поскольку функция DumpIt () принимает базовый объект по значению, новый временный базовый объект создается на основе оригинала. Чтобы получить ожидаемую функциональность, вам нужно передать по ссылке или по указателю:

void DumpIt(Base & b)
{
    b.dump();
}

Вывод этой функции - «Der».

6
задан Martin 17 June 2009 в 22:38
поделиться

4 ответа

Если вы не используете Не обращайте внимания на дерьмовую случайность, классический метод -

x[n+1] = (x[n] * x[n] + C) mod N

, где C и N - константы, C! = 0 и C! = -2, а N - простое число. Это типичный псевдослучайный генератор для факторинга Полларда Ро. Попробуйте C = 1 и N = 8051, они работают нормально.

5
ответ дан 9 December 2019 в 22:39
поделиться

Хотите верьте, хотите нет, но я использовал newx = oldx * 5 + 1 (или небольшую его вариацию) в нескольких видеоиграх. Случайность ужасна - это скорее скремблированная последовательность, чем случайный генератор. Но иногда это все, что вам нужно. Если я правильно помню, он перебирает все числа перед повторением.

У него ужасные характеристики. Он никогда не дает вам одно и то же число дважды подряд. Некоторые из нас провели кучу тестов на его вариациях, и мы использовали некоторые вариации в других играх.

Мы использовали его, когда нам не было подходящего модуля. Это просто сдвиг на два и два сложения (или умножение на 5 и одно сложение). Я бы никогда не использовал его сейчас для случайных чисел - я бы использовал LCG - но, возможно, он будет работать нормально для шейдера, где скорость имеет решающее значение, а ваш набор инструкций может быть ограничен.

2
ответ дан 9 December 2019 в 22:39
поделиться

Используйте линейный конгруэнтный генератор :

X_(n+1) = (a * X_n + c) mod m

Они не так сильны, но, по крайней мере, они хорошо известны и могут иметь длительные периоды. На странице Википедии также есть хорошие рекомендации:

Период общей LCG не превышает м, а для некоторых вариантов гораздо меньше чем это. LCG будет иметь полную период тогда и только тогда, когда:

 1. c и m взаимно просты,
2. a - 1 делится на все простые делители m,
3. a - 1 делится на 4, если m делится на 4
2
ответ дан 9 December 2019 в 22:39
поделиться

В вершинных шейдерах иногда есть встроенные генераторы шума, которые можно использовать, например, функция cg noise () .

2
ответ дан 9 December 2019 в 22:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: