设为首页 加入收藏

TOP

C++ 随机数(四)
2019-05-23 16:11:11 】 浏览:134
Tags:随机
ht is 0."); return; } } }; //End of namespace Lunacia.

Random.cpp

#include "Random.h"

namespace Lunacia
{
    //Random
    std::mt19937_64 Random::baseGener;
    LARGE_INTEGER Random::sysTime;

    std::atomic<uint64_t> Random::ranCount = 0LL;
    const uint64_t Random::RandBase = 100000000LL;

    Random::Random()
    {
        Random::Init();
    }

    Random::~Random()
    {
        Reset();
    }

    void Random::Init(bool isPRNG, uint64_t inSeed)
    {
        if (isPRNG)
        {
            baseGener.seed(inSeed);
            return;
        }

        //QueryPerformanceCounter
        LARGE_INTEGER _freq;
        LARGE_INTEGER _count;

        QueryPerformanceFrequency(&_freq);
        QueryPerformanceCounter(&_count);

        sysTime.QuadPart = _count.QuadPart * 1000000 / _freq.QuadPart;

        uint64_t seed = sysTime.QuadPart;
        if (seed == 0LL)
        {
            WarningThrow("QueryPerformanceFrequency function is nonsupport.");

            //Initializating the seed by time.
            {
                using namespace std::chrono;
                time_point<system_clock, milliseconds> tp = \
                    time_point_cast<milliseconds>(system_clock::now());
                auto tmp = duration_cast<milliseconds>(tp.time_since_epoch());

                seed = tmp.count();
            }
        }

        baseGener.seed(seed);
    }

    void Random::Reset()
    {
        baseGener.seed();

        ranCount = 0LL;
    }

    uint64_t Random::GetRandNum()
    {
        const uint64_t& ret = baseGener();
        SyncSeed();

        return ret;
    }

    void Random::SyncSeed()
    {
        static const uint64_t& period =
            (static_cast<uint64_t>(std::powl(2, (baseGener.word_size * (baseGener.state_size - 1))) - 1)) / baseGener.state_size;

        if (++ranCount >= period)
        {
            ranCount = 0LL;
            Init();
        }
    }

    //RandomAvg
    std::uniform_int_distribution<uint64_t> RandomAvg::avgNum;

    RandomAvg::RandomAvg()
    {
        RandomAvg::Init();
    }

    RandomAvg::~RandomAvg()
    {
        RandomAvg::Reset();
    }

    void RandomAvg::Init()
    {
        Random::Init();
    }

    void RandomAvg::Reset()
    {
        RandomAvg::avgNum.reset();
    }

    uint64_t RandomAvg::GetRandNum()
    {
        baseGener.discard(sysTime.LowPart % baseGener.state_size);
        SyncSeed();

        return avgNum(baseGener);
    }

    //Return [min, max).
    uint64_t RandomAvg::GetRandNum(const uint64_t& min, const uint64_t& max)
    {
        if (min >= max)
        {
            ErrorThrow(
                "RandomAvg::GetAveNum The minimum cannot be greater than or equal to the maximum. "
                "min: " + std::to_string(min) + "; max: " + std::to_string(max) + "."
            );
            return 0LL;
        }
        return GetRandNum() % (max - min) + min;
    }

    bool RandomAvg::HitProbability(const double& prob)
    {
        if (prob >= 1.0)
        {
            return true;
        }

        if (prob <= 0.0)
        {
            return false;
        }

        const uint64_t randNum = GetRandNum(0, RandBase) + 1;
        uint64_t exp = static_cast<uint64_t>(prob * RandBase);

        return randNum <= exp;
    }

    uint64_t RandomAvg::HitExpectation(const double & prob)
    {
        if (static_cast<int>(prob) >= 1)
        {
            return 1;
        }

        if (prob <= 0.0)
        {
            return 0;
        }

        uint64_t rand = GetRandNum(0, RandBase);
        return static_cast<uint64_t>((rand + 1) * (1.0 / prob)) / RandBase + 1;
    }

    //Norm

    RandomNorm::RandomNorm() :
        RandomNorm(0.0, 1.0)
    {
    }

    RandomNorm::RandomNorm(long double avg, long double stdDev)
    {
        Init(avg, stdDev);
    }

    RandomNorm::~RandomNorm()
    {
        Clear();
    }

    void RandomNorm::Init(const long double& avg, const long double& stdDev)
    {
        _avg = avg;
        _stdDev = stdDev;

        Random::Init();
        delete ptrNormNum;
首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++中的赋值操作符重载和拷贝构造.. 下一篇普通Splay详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目