• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Error

            C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
              217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks
            // RandomTest.cpp : Defines the entry point for the console application.
            //

            #include "stdafx.h"

            #include <iostream>
            #include <cmath>
            #include <random>
            #include <cstdint>
            #include <ctime>
            #include <algorithm>
            #include <numeric>
            #include <cassert>
            #include <climits>
            #include <thread>

            #define XASSERT(exp) assert(exp)
            #define XASSERT_MSG(exp, msg) assert(exp)
            #define X_DEFAULT_FLOAT_PRECISION (0.00000001)

            // @in: 總次數(shù)、目標(biāo)比例(千分比)、算法類型(1.c標(biāo)準(zhǔn)庫rand; 2.cpp11 mt19937)
            // @out: 實際命中次數(shù)、實際命中概率
            bool RandomHitTest(int32_t nTotalCount, float fHitRate, int32_t nAlgorithmType, int32_t& nRealHitCount, float& fRealHitRate);
            void RandomHitTest_std_mt19937(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate);
            void RandomHitTest_std_rand(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate);
            // 簡化std::rand獲取[nMin, nMax]區(qū)間的一個數(shù)字
            uint32_t StdRandEx(uint32_t nMin, uint32_t nMax);


            int _tmain(int argc, _TCHAR* argv[])
            {
                //std::thread srandThread([](){ std::this_thread::sleep_for(std::chrono::seconds(1));});
                
            //srandThread.detach();

                std::vector<std::tuple<floatfloat>> vecResult;

                for (int n = 0; n < 1000; n++)
                {
                    uint32_t nTotalCount = 100000;  // 基數(shù)100000次

                    for (float fHitRate = 0.001f; 1.f - fHitRate >= 0; fHitRate = fHitRate + 0.101f)
                    {
                        int32_t nRealHitCount = 0;
                        float fRealHitRate = 0;

                        // std::rand測試
                        RandomHitTest(nTotalCount, fHitRate, 1, nRealHitCount, fRealHitRate);
                        //std::cout << "AlgorithmType=" << 1 << ",TotlaCount=" << nTotalCount << ",HitRate=" << 
                        
            //    fHitRate  << ",ReahHitRate=" << std::fixed << fRealHitRate << ",RealHitCount=" << nRealHitCount << std::endl;


                        int32_t nRealHitCount1 = 0;
                        float fRealHitRate1 = 0;

                        // cpp11 mt19937
                        RandomHitTest(nTotalCount, fHitRate, 2, nRealHitCount1, fRealHitRate1);
                        //std::cout << "AlgorithmType=" << 2 << ",TotlaCount=" << nTotalCount << ",HitRate=" << 
                        
            //    fHitRate  << ",ReahHitRate=" << std::fixed << fRealHitRate1 << ",RealHitCount=" << nRealHitCount1 << std::endl;
                        
            //std::cout << "---differ rate=" << std::fixed << fRealHitRate1 - fRealHitRate << ", differ count=" 
                        
            //    << nRealHitCount1 - nRealHitCount << std::endl;

                        std::tuple<floatfloat> tupleResult = std::make_tuple(fHitRate, std::fabsf(fRealHitRate1 - fRealHitRate));
                        vecResult.push_back(tupleResult);
                    }
                }

                std::sort(vecResult.begin(), vecResult.end(), 
                    [](std::tuple<floatfloat>& tupLeft, std::tuple<floatfloat>& tupRight)->bool{
                        //float fHitRateL = 0;
                        
            //float fRealRateL = 0;

                        
            //float fHitRateR = 0;
                        
            //float fRealRateR = 0;
                        return std::get<1>(tupLeft) - std::get<1>(tupRight) > 0;;
                });

                auto tupleFirst = vecResult[0];

                return 0;
            }


            uint32_t StdRandEx(uint32_t nMin, uint32_t nMax)
            {
                XASSERT((nMin >= 0) && (nMax >= 0) && (nMin <= nMax));

                uint32_t nRandVal = 0;

                if (nMin == nMax)
                {
                    nRandVal = nMax;
                }
                else if (nMin < nMax)
                {
                    nRandVal = rand() % (nMax - nMin + 1) + nMin;
                }
                else
                {
                    XASSERT_MSG(0, _T("參數(shù)異常"));
                }

                return nRandVal;
            }

            void RandomHitTest_std_rand(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate)
            {
                nRealHitCount = 0;
                fRealHitRate = 0;

                if (nTotalCount <= 0 || fHitRate <= 0)
                {
                    return;
                }

                // 計算浮點小數(shù)點個數(shù)
                int32_t nWeCount = 3;  // 位數(shù)(三位數(shù),千分比精度)
                XASSERT((fHitRate * std::pow(10, nWeCount)) - std::numeric_limits<uint64_t>::max() <= X_DEFAULT_FLOAT_PRECISION);  // 永不溢出
                int64_t nHitRateIntHelp = static_cast<uint64_t>(fHitRate * std::pow(10, nWeCount));  // 概率轉(zhuǎn)整數(shù)輔助計算

                
            // 根據(jù)位數(shù)決定隨機數(shù)范圍
                int32_t nRandMin = 0;
                int32_t nRandMax = std::pow(10, nWeCount);

                // 開始測試
                auto nTestCount = nTotalCount;
                while (nTestCount-- > 0)
                {
                    // 生成隨機數(shù)
                    int32_t nRandVal = StdRandEx(nRandMin, nRandMax);

                    // 命中判定
                    if (nRandVal < nHitRateIntHelp)
                    {
                        nRealHitCount++;
                    }
                }

                fRealHitRate = float(nRealHitCount)/float(nTotalCount);
            }

            void RandomHitTest_std_mt19937(int32_t nTotalCount, float fHitRate, int32_t& nRealHitCount, float& fRealHitRate)
            {
                nRealHitCount = 0;
                fRealHitRate = 0;

                if (nTotalCount <= 0 || fHitRate <= 0)
                {
                    return;
                }

                // 計算浮點小數(shù)點個數(shù)
                int32_t nWeCount = 3;  // 位數(shù)(三位數(shù),千分比精度)
                XASSERT((fHitRate * std::pow(10, nWeCount)) - std::numeric_limits<uint64_t>::max() <= X_DEFAULT_FLOAT_PRECISION);  // 永不溢出
                int64_t nHitRateIntHelp = static_cast<uint64_t>(fHitRate * std::pow(10, nWeCount));  // 概率轉(zhuǎn)整數(shù)輔助計算

                
            // 根據(jù)位數(shù)決定隨機數(shù)范圍
                int32_t nRandMin = 0;
                int32_t nRandMax = std::pow(10, nWeCount);

                // 設(shè)置隨機數(shù)生成器
                std::random_device rd;
                std::mt19937_64 gen(rd());
                std::uniform_int_distribution<> dis(nRandMin, nRandMax);
                
                // 重設(shè)種子應(yīng)該使用這個api:::CryptGenRandom
                
            // linux也有相應(yīng)的高精度隨機數(shù)
                gen.seed(uint32_t(time(NULL)));

                // 開始命中測試
                auto nTestCount = nTotalCount;
                while (nTestCount-- > 0)
                {
                    // 生成隨機數(shù)
                    uint32_t randVal = dis(gen);

                    if (randVal < nHitRateIntHelp)
                    {
                        nRealHitCount++;
                    }
                }

                fRealHitRate = float(nRealHitCount)/float(nTotalCount);
            }


            bool RandomHitTest(int32_t nTotalCount, float fHitRate, int32_t nAlgorithmType, int32_t& nRealHitCount, float& fRealHitRate)
            {
                if (nTotalCount <= 0)
                {
                    return false;
                }

                bool bRet = true;
                switch (nAlgorithmType)
                {
                case 1:
                    RandomHitTest_std_rand(nTotalCount, fHitRate, nRealHitCount, fRealHitRate);
                    break;
                case 2:
                    RandomHitTest_std_mt19937(nTotalCount, fHitRate, nRealHitCount, fRealHitRate);
                    break;
                default:
                    bRet = false;
                    break;
                }

                return true;
            }

            posted on 2017-01-22 12:28 Enic 閱讀(1327) 評論(0)  編輯 收藏 引用 所屬分類: 從零開始寫棋牌游戲平臺
            亚洲精品乱码久久久久久按摩 | 亚洲香蕉网久久综合影视| 日韩电影久久久被窝网| 久久人人爽人人爽人人av东京热 | 久久精品国产亚洲AV高清热 | 久久久久这里只有精品| 久久只这里是精品66| 午夜不卡久久精品无码免费 | 一本久道久久综合狠狠躁AV| 久久精品国产99国产精品导航| 2021久久国自产拍精品| 青青热久久国产久精品| 伊人色综合久久天天| 中文字幕无码免费久久| 久久99精品九九九久久婷婷| 久久中文骚妇内射| 女人高潮久久久叫人喷水| 久久精品国产第一区二区| 精品久久久久久综合日本| 亚洲中文字幕无码久久2020| 欧美性猛交xxxx免费看久久久| 亚洲国产成人久久综合一| 久久精品无码专区免费东京热| 国产精品亚洲综合久久| 婷婷久久精品国产| 久久天天躁狠狠躁夜夜不卡| 国产精品久久永久免费| 精品乱码久久久久久久| 久久天天躁狠狠躁夜夜avapp| 午夜精品久久久久9999高清| 夜夜亚洲天天久久| 久久精品国产精品青草app| 91精品国产高清91久久久久久 | 久久国产精品免费一区二区三区| aaa级精品久久久国产片| 久久久久人妻精品一区二区三区 | 久久er国产精品免费观看8| 久久久久久久综合日本亚洲| 久久婷婷久久一区二区三区| 97久久综合精品久久久综合| 久久久久免费精品国产|