为何这段代码始终生成0而非随机数?如何修复该问题?
问题排查与修复方案
咱们来一步步拆解你代码里的问题,为什么它总是输出0:
核心问题分析
关键成员变量未初始化
你的mRND类构造函数里,只初始化了_m,但_a和_c这两个线性同余生成器(LCG)的核心参数被默认初始化为0了。这样在rnd()方法里,计算式(_a * _seed + _c) % _m就变成了0 * _seed + 0,结果自然永远是0。seed()方法从未被调用
就算你初始化了_a和_c,_seed在构造时是默认的0值,你没有调用seed()方法去给它设置初始随机种子,所以后续计算还是基于0,结果还是0。构造函数访问权限错误
原代码里mRND的构造函数被声明为protected,这会导致你在main()里直接创建mRND r的时候编译报错(除非你是把它当基类用,但这里显然不是),这个得改成public才能正常实例化对象。
修复后的代码
这里我给你调整了代码,修复了所有问题,还选用了标准LCG的参数(这些参数是经过验证的,能生成较好的随机序列):
#include <iostream> #include <stdlib.h> #include <time.h> using namespace std; class mRND { public: // 把构造函数改成public,并且初始化_a和_c为标准LCG参数 mRND() : _a(1103515245), _c(12345), _m(2147483648), _seed(0) {} void seed() { // 用当前时间初始化系统随机数生成器,再给_seed赋值 srand(time(0)); _seed = rand(); } // 把rnd()改成public,不然main里调用不了 int rnd() { // 转成unsigned long long避免整数溢出 _seed = (_a * static_cast<unsigned long long>(_seed) + _c) % _m; return static_cast<int>(_seed); } private: // 把成员变量改成private更符合封装原则 int _a, _c; unsigned int _m, _seed; }; int main() { mRND r; // 必须先调用seed()初始化种子 r.seed(); for(int i = 0; i < 10; i++) { // 改成输出10个,方便查看结果 cout << r.rnd() << endl; } return 0; }
额外说明
- LCG参数选择:我用的
_a=1103515245和_c=12345是glibc库中rand()函数使用的参数,属于经过测试的靠谱参数,能保证生成的随机数序列质量。 - 溢出避免:在计算
_a * _seed的时候,我把_seed转成了unsigned long long,因为_a是int类型,乘以_seed(unsigned int)可能会溢出,转成64位整数能避免这个问题。 - 封装优化:把成员变量改成
private,只暴露必要的seed()和rnd()方法,更符合面向对象的封装原则。
内容的提问来源于stack exchange,提问作者raneem
相关产品推荐
相关产品推荐

