rand

Discussion in 'WASM.BEGINNERS' started by sato, Sep 17, 2017.

  1. sato

    sato Забанен

    Blog Posts:
    0
    Joined:
    Jan 15, 2012
    Messages:
    5
    почему максимальное псевдослучайное число не FFFF как наверно должно быть
    ,а 7FFF ?
     
  2. Rel

    Rel Well-Known Member

    Blog Posts:
    2
    Joined:
    Dec 11, 2008
    Messages:
    5,317
    https://ru.wikipedia.org/wiki/Линейный_конгруэнтный_метод - читаем матчасть... если читать лень, то: "для улучшения статистических свойств числовой последовательности во многих генераторах псевдослучайных чисел используется только часть битов результата. Например, в стандарте ISO/IEC 9899 на язык Си приведен (но не указан в качестве обязательного) пример функции rand(), принудительно отбрасывающей младшие 16 и один старший разряд."
     
    Indy_ and yashechka like this.
  3. Мановар

    Мановар Active Member

    Blog Posts:
    0
    Joined:
    Dec 2, 2016
    Messages:
    143
    Наверное, потому что FFFF = -1, а 7FFF = 32767, что соответствует RAND_MAX при применении rand().
    Но сейчас куча других подходов (например, что то типа этого).
    Code (ASM):
    1.  
    2. #include "stdafx.h"
    3. #include <iostream>
    4. #include <random>
    5. #include <ctime>
    6. template <typename T1>
    7. T1 getRandNumber(const T1 && begin, const T1 && end)
    8. {
    9. static std::mt19937 generator(time(0));
    10. std::uniform_real_distribution<> distribution(begin, end);
    11. return distribution(generator);
    12. }
    13. int main()
    14. {
    15. std::cout << "(long long): " << getRandNumber<long long>(1000000000000, 1000000000000000000) << std::endl
    16. << "(double):" << getRandNumber<double>(-234.45, 6574.75) << std::endl
    17. << "(int):" << getRandNumber<int>(-100000, 100000) << std::endl;
    18. system("pause");
    19. }
    20.  
    p0936.png
     

    Attached Files:

    Last edited: Sep 17, 2017
  4. rmn

    rmn Well-Known Member

    Blog Posts:
    0
    Joined:
    Nov 23, 2004
    Messages:
    2,347
    Потому что сначала нужно вызывать
    Code (C):
    1. srand(GetTickCount());
     
    sato likes this.
  5. al79

    al79 Алексей

    Blog Posts:
    0
    Joined:
    May 11, 2006
    Messages:
    133
    Location:
    Екатеринбург
    Если нужно больше:
    Code (ASM):
    1. push 0
    2. mov ebx,esp
    3. invoke CryptAcquireContext,ebx,0,0,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT
    4. pop ebx
    5. invoke CrpytGenRandom,ebx,(длина в байтах),(куда положить)
    6. invoke CrpytReleaseContext,ebx,0
     
    yashechka likes this.
  6. Intro

    Intro Active Member

    Blog Posts:
    0
    Joined:
    Aug 29, 2009
    Messages:
    614
    В XRay используется такой алгоритм.
    Code (C++):
    1. ICN   s32     randI   ()               { return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff); }
    Проблема в том что, генерация последовательности совсем не случайная, например при массовой генерации случайных векторов(создания осколков при взрыве взрывных объектов) они тяготят к северу и к югу, т.е. есть резкая неравномерность. Пробовал использовать RDTSC, но тогда время выполнения увеличивается с 10 тактов до 70, на атлон 64 II эта команда выполняется тактов 60.
    А какие ещё есть быстрые генераторы? Длина последовательности может быть не очень большой, важна именно равномерность генерации.
     
  7. SadKo

    SadKo Владимир Садовников

    Blog Posts:
    8
    Joined:
    Jun 4, 2007
    Messages:
    1,610
    Location:
    г. Санкт-Петербург
    Intro, используйте несколько генераторов и дёргайте их по очереди. Подберите только разные коэффициенты и разный seed.
     
  8. RET

    RET Well-Known Member

    Blog Posts:
    17
    Joined:
    Jan 5, 2008
    Messages:
    789
    Location:
    Jabber: darksys@sj.ms
    Вызывайте и склеивайте, добавляйте солите и что хотите ;)
    Code (Text):
    1. INT x_rand(void)
    2. {
    3.     int r;
    4.     __asm
    5.     {
    6.         pushad
    7.             rdtsc
    8.             xor        edx, edx
    9.             dec        edx
    10.             shr        edx, 1
    11.             and        eax, edx
    12.             mov        r, eax
    13.             popad
    14.     }
    15.     return r;
    16. }
     
  9. Indy_

    Indy_ Well-Known Member

    Blog Posts:
    4
    Joined:
    Apr 29, 2011
    Messages:
    4,788
    RET,

    TSC является линейным счётчиком и не может быть использован в быстром цикле. Значение этого счетчика может служить magic-значением для дальнейшего вычисления рандом функции. Но если непрерывно использовать данный счётчик, то функция станет не рандом, в ней будут линейные закономерности, это значит что рандом функция станет вычисляемой.