#property copyright "Mateev"
#property version "1.0"
#property link " "
#property description " "
#property strict " "
double probability;
void start()
{ RandomTick();}
//================================================== ===========
// Функцията връща +1 или -1 с вероятност probability, като гарантира,
// че няма да се появи повторяемост дори и след милиарди извиквания.
// Променливата probability трябва да е в диапазона от 0 до 1
int RandomTick()
{
if (probability <=0) return(-1); // При вероятност 0 ( 0%) винаги връщаме -1
if (probability >=1) return( 1); // При вероятност 1 (100%) винаги връщаме +1
// Статични променливи, инициализацията на които се изпълнява само веднъж в хода на програмата,
// и след това си пазят стойноста между отделните извиквания на функцията
static ulong counter=0; // Брояч, който нараства с 1-ца при всяко едно теглене на нов тик
static ulong random =0; // Случайно число, от байтовете на което ще се теглят тиковете
// Младшите 3 бита на counter са индекса на байта, от който ще се тегли следващия тик
ulong byteID = counter & ulong(B'111');
// Веднъж на всеки 8 извиквания на функцията се преизчислява 64-битовото случайно число random,
// от 8-те байта на което в 8 последователни извиквания ще се изтегли по 1 случаен тик
if (byteID == 0) // Ако индекса на байта е равен на 0, значи е време за преизчисляване на random
{
// Осигуряваме си неповтаряща се последователност от числа в променливата random,
// при която броя на нулите и единиците е приблизително еднакъв в безкрайноста
random = GetMicrosecondCount() ^ counter;
// XOR-ваме 64-те бита на random посредством няколко псевдослучайни 15 битови числа
random = random ^ (ulong(MathRand())); // XOR-ваме първите 15 бита (битове 0..14)
random = random ^ (ulong(MathRand())<<15); // XOR-ваме следващите 15 бита (битове 15..29)
random = random ^ (ulong(MathRand())<<30); // XOR-ваме следващите 15 бита (битове 30..44)
random = random ^ (ulong(MathRand())<<45); // XOR-ваме следващите 15 бита (битове 45..59)
random = random ^ (ulong(MathRand())<<60); // XOR-ваме следващите 4 бита (битове 60..63)
}
counter++;
// Вземане на 8-те бита на този байт от random, който е определен с byteID
// В резултат на операцията (местене на дясно и AND-ване), в младшите 8 бита остава случайно число от 0 до 255
ulong byte = (random >> (byteID*8)) & B'11111111';
// Мащабиране на случайно число byte така, щото диапазона му да стане double от 0.0 до 1.0,
double rnd = double(byte) / 256.0;
// Изчисляване на тик с вероятност probability
if (probability > rnd) return(1);
else return(-1);
}