【问题标题】:Linear Congruential Generator, operators & and >> in C++C++ 中的线性同余生成器、运算符 & 和 >>
【发布时间】:2015-10-11 10:34:08
【问题描述】:

我正在研究线性同余生成器。 公式为:

Xn+1 = (a * Xn + c) mod m

我在 C++ 中发现了这样一段代码实现 LCG:

class LCG {
public:
    LCG();
    LCG(unsigned int newSeed);
    ~LCG();
    void setSeed(unsigned int newSeed);
    unsigned int getSeed(void);
    unsigned int next(void);
private:
    unsigned int seed;
    const static unsigned int a = 214013U;
    const static unsigned int c = 2531011U;
};

LCG::LCG() { seed = 1; }
LCG::LCG(unsigned int newSeed) { setSeed(newSeed); }
LCG::~LCG() { }
void LCG::setSeed(unsigned int newSeed) { seed = newSeed; }
unsigned int LCG::getSeed(void) { return seed; }
unsigned int LCG::next(void) {
    seed = (seed * a + c) & 0xffffffff;
    return (seed >> 16) & 0x7fff;
}

在最后两行代码中,我不明白运算符&和>>的用法。如果有人可以帮助我,我将不胜感激。

【问题讨论】:

  • 您不了解这些运算符,或者您不了解它们在这种情况下的应用吗?
  • 当然,在这种情况下。
  • 最后一个运算符将生成的随机值除以 2^16。比通过应用位掩码剪切最后一位。这可能用于选择生成值的特定部分。
  • 第一个&没用。即使unsigned int 有“太多位”,它们也无法影响低位。只有低 31 位才重要。

标签: c++ algorithm random


【解决方案1】:

第一个“&”在您的公式中执行“mod”,m=2^32。 (大概这是针对 64 位整型架构的,因为它对于 32 位整型而言是无操作的。)

第二行是整数除以 2^16,然后是 (mod 2^15)——数学上等价于 (seed / 65536) % 32768。

使用其他计算方法的原因是这些“按位”运算符相对于等效的“数学”运算具有几乎可以肯定的时间效率。

【讨论】:

  • 第一个&实际上也是64位的nop,它可以编译成一些指令但不会影响结果。
  • 虽然不影响next()的返回值。它肯定会影响种子的价值,考虑到有一个 getseed() 方法,这显然很重要。
  • 如果您确实需要,当然可以将& 移至getseed
  • 它还可以防止后续 (seed*a+c) 操作的溢出,溢出是 c++ 中未定义结果的条件。
  • 它只是签名类型的 UB,此外,如果这是一个问题,代码在 32 位系统上会出错
猜你喜欢
  • 1970-01-01
  • 2015-08-22
  • 2013-10-09
  • 2012-08-19
  • 1970-01-01
  • 2016-07-03
  • 2013-07-11
  • 1970-01-01
  • 2019-11-29
相关资源
最近更新 更多