C++ 和 Python(随机数生成器)之间的整数计算结果不匹配
Mismatch in integer calculation results between C++ and Python (random number generator)
我的一个项目需要一个伪随机数生成方案(独立于标准库),我尝试了一个简单的基于 LCG 的 RNG。它似乎工作正常,只是它在 C++ 和 Python 中产生不同的值。我在下面给出了两者的相关代码。我找不到错误。任何帮助将不胜感激!
(c++)
// file: lgc.cc
// compile and run with: g++ lgc.cc -o lgc && ./lgc
#include <cstdio>
#include <cstdint>
#include <vector>
using namespace std;
uint64_t LGC(uint64_t x) {
uint64_t A = 1103515245;
uint64_t C = 12345;
uint64_t M = (1 << 31);
return (A * x + C) % M;
}
int main(int argc, char* argv[]) {
for (auto x : {485288831, 485288832, 10, 16, 255, 756}) {
uint64_t y = LGC(x);
printf("%u %u\n", (uint32_t)x, (uint32_t) y);
}
return 0;
}
(python)
# file: lgc.py
# run with: python3 lgc.py
def LGC(x):
A = 1103515245;
C = 12345;
M = int(2 ** 31);
return (A * x + C) % M;
for x in [485288831, 485288832, 10, 16, 255, 756]:
y = LGC(x)
print(x, y)
(结果:c++)
485288831 3822790476
485288832 631338425
10 2445230203
16 476387081
255 2223525580
756 1033882141
(结果:python)
485288831 1675306828
485288832 631338425
10 297746555
16 476387081
255 76041932
756 1033882141
问题在于移位:uint64_t M = (1 << 31);
对于 32 位整数,(1<<31)
是一个负数 -2147483648
,因为这是有符号整数数学运算。要解决此问题,您可以使用 uint64_t M = (1U << 31);
使移位使用无符号 32 位整数。您还可以使用 uint64_t M = (1UL << 31);
让计算使用 64 位无符号整数
以下 link 显示在具有 32 位 int 的系统上打印 (1 << 31)
、(1U << 31)
和 (1UL << 31)
的输出:
https://ideone.com/vU0eyX
我的一个项目需要一个伪随机数生成方案(独立于标准库),我尝试了一个简单的基于 LCG 的 RNG。它似乎工作正常,只是它在 C++ 和 Python 中产生不同的值。我在下面给出了两者的相关代码。我找不到错误。任何帮助将不胜感激!
(c++)
// file: lgc.cc
// compile and run with: g++ lgc.cc -o lgc && ./lgc
#include <cstdio>
#include <cstdint>
#include <vector>
using namespace std;
uint64_t LGC(uint64_t x) {
uint64_t A = 1103515245;
uint64_t C = 12345;
uint64_t M = (1 << 31);
return (A * x + C) % M;
}
int main(int argc, char* argv[]) {
for (auto x : {485288831, 485288832, 10, 16, 255, 756}) {
uint64_t y = LGC(x);
printf("%u %u\n", (uint32_t)x, (uint32_t) y);
}
return 0;
}
(python)
# file: lgc.py
# run with: python3 lgc.py
def LGC(x):
A = 1103515245;
C = 12345;
M = int(2 ** 31);
return (A * x + C) % M;
for x in [485288831, 485288832, 10, 16, 255, 756]:
y = LGC(x)
print(x, y)
(结果:c++)
485288831 3822790476
485288832 631338425
10 2445230203
16 476387081
255 2223525580
756 1033882141
(结果:python)
485288831 1675306828
485288832 631338425
10 297746555
16 476387081
255 76041932
756 1033882141
问题在于移位:uint64_t M = (1 << 31);
对于 32 位整数,(1<<31)
是一个负数 -2147483648
,因为这是有符号整数数学运算。要解决此问题,您可以使用 uint64_t M = (1U << 31);
使移位使用无符号 32 位整数。您还可以使用 uint64_t M = (1UL << 31);
让计算使用 64 位无符号整数
以下 link 显示在具有 32 位 int 的系统上打印 (1 << 31)
、(1U << 31)
和 (1UL << 31)
的输出:
https://ideone.com/vU0eyX