声明
class DLL_SN_EXT_CLASS CRand32 { public: CRand32(); unsigned int rand(); bool Prize(double dOdds);//中奖几率,dOdds<=0,必定不中;dOdds>=1 必中 protected: unsigned int m_iSeed; /* Seed variables */ static int s_iObjNum; };
优点:
一,不需要随机种子,多个对象会随机不同的种子。
二,范围和UINT的范围同
实现
int CRand32::s_iObjNum = 0; CRand32::CRand32() { m_iSeed = ::time(NULL) + s_iObjNum++; } unsigned int CRand32::rand() { m_iSeed = 214013 * m_iSeed + 2531011; return m_iSeed; } bool CRand32::Prize(double dOdds)//中奖几率,dOdds<=0,必定不中;dOdds>=1 必中 { return (double)rand() / UINT_MAX < dOdds; }
测试样例
TEST_METHOD(RAND32_1) {// n 个对象的第一个随机数,一定不相同 const int n = 100; SN::CRand32 rs[n]; int iRs[n] = { 0 }; { for (int i = 0; i < n; i++) { iRs[i] = rs[i].rand(); } } { for( int i = 0 ; i < n ; i++ ) for (int j = i + 1; j < n; j++) { Assert::AreNotEqual(iRs[i], iRs[j]); } } } TEST_METHOD(RAND32_2) {//随机次数足够多,每位为0,1的几率稳定(正负10%) SN::CRand32 rand ; int a[32] = { 0 }; const int iNum = 10000000; for (int i = 0; i < iNum; i++) { unsigned int r = rand.rand(); for (int j = 0; j < 32; j++) { a[j] += ((r >> j) & 0x1); } } { for (int i = 0; i < 32; i++) { CString s; s.Format(_T("%d"), i); Assert::IsTrue(abs(a[i] - iNum / 2) < iNum / 20,s); } } } TEST_METHOD(RAND32_3) { SN::CRand32 r; const int iNum = 10000000; int a[5] = { 0 }; for (int i = 0; i < iNum; i++) { a[0] += r.Prize(0); a[1] += r.Prize(0.0001); a[2] += r.Prize(0.5); a[3] += r.Prize(0.99); a[4] += r.Prize(100); } Assert::AreEqual(a[0], 0); Assert::IsTrue(abs(a[1]- iNum / 10000) < iNum / 100000); Assert::IsTrue(abs(a[2] - iNum / 2) < iNum / 20); Assert::IsTrue(abs(a[3] - iNum *0.99) < iNum *0.99/ 10); Assert::AreEqual(a[4], iNum); }