https://ru.wikipedia.org/wiki/Линейный_конгруэнтный_метод - читаем матчасть... если читать лень, то: "для улучшения статистических свойств числовой последовательности во многих генераторах псевдослучайных чисел используется только часть битов результата. Например, в стандарте ISO/IEC 9899 на язык Си приведен (но не указан в качестве обязательного) пример функции rand(), принудительно отбрасывающей младшие 16 и один старший разряд."
Наверное, потому что FFFF = -1, а 7FFF = 32767, что соответствует RAND_MAX при применении rand(). Но сейчас куча других подходов (например, что то типа этого). Code (ASM): #include "stdafx.h" #include <iostream> #include <random> #include <ctime> template <typename T1> T1 getRandNumber(const T1 && begin, const T1 && end) { static std::mt19937 generator(time(0)); std::uniform_real_distribution<> distribution(begin, end); return distribution(generator); } int main() { std::cout << "(long long): " << getRandNumber<long long>(1000000000000, 1000000000000000000) << std::endl << "(double):" << getRandNumber<double>(-234.45, 6574.75) << std::endl << "(int):" << getRandNumber<int>(-100000, 100000) << std::endl; system("pause"); } p0936.png
Если нужно больше: Code (ASM): push 0 mov ebx,esp invoke CryptAcquireContext,ebx,0,0,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT pop ebx invoke CrpytGenRandom,ebx,(длина в байтах),(куда положить) invoke CrpytReleaseContext,ebx,0
В XRay используется такой алгоритм. Code (C++): ICN s32 randI () { return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff); } Проблема в том что, генерация последовательности совсем не случайная, например при массовой генерации случайных векторов(создания осколков при взрыве взрывных объектов) они тяготят к северу и к югу, т.е. есть резкая неравномерность. Пробовал использовать RDTSC, но тогда время выполнения увеличивается с 10 тактов до 70, на атлон 64 II эта команда выполняется тактов 60. А какие ещё есть быстрые генераторы? Длина последовательности может быть не очень большой, важна именно равномерность генерации.
Intro, используйте несколько генераторов и дёргайте их по очереди. Подберите только разные коэффициенты и разный seed.
Вызывайте и склеивайте, добавляйте солите и что хотите Code (Text): INT x_rand(void) { int r; __asm { pushad rdtsc xor edx, edx dec edx shr edx, 1 and eax, edx mov r, eax popad } return r; }
RET, TSC является линейным счётчиком и не может быть использован в быстром цикле. Значение этого счетчика может служить magic-значением для дальнейшего вычисления рандом функции. Но если непрерывно использовать данный счётчик, то функция станет не рандом, в ней будут линейные закономерности, это значит что рандом функция станет вычисляемой.