请原谅这篇文章令人作呕的愚蠢性质,但我有一个问题要问那些在个人计算机上使用 C++ 和 R 编程的人。
问题:为什么下面两个程序产生的这些随机数不相等,我该如何解决这个问题?
- 首先,我怀疑我在 R 程序中误用了
local
函数和运算符。<<-
- 其次,我怀疑这可能是一个浮动精度问题。对我来说,这两个程序有什么不同并不是很明显,所以我不知道如何解决这个问题。
我已经尝试将我在 C++ 中的所有计算转换为double
/ float
(偶数long double
),并使用fmod
而不是模运算符%
: 再次输出不同的输出,但仍然与 R 中的输出不相似。我不知道它是否有任何重要意义,但我想补充一点,我正在使用 G++ 编译器编译 C++ 代码。
算法:以下算法可用于任何标准个人计算机。建议并行使用三个单词生成器,
- m k = 171 m k-1 (mod 30269)
- m' k = 172 m' k-1 (mod 30307)
- m'' k = 172 m'' k-1 (mod 30323)
并将小数部分用作伪随机数
- g k = { m k / 30269 + m' k / 30307 + m'' k / 30323}
我使用了初始值m 0 = 5、m' 0 = 11 和m'' 0 = 17。
程序:我在 C++ 中有以下程序:
//: MC:Uniform.cpp
// Generate pseudo random numbers uniformly between 0 and 1
#include <iostream>
#include <math.h> // For using "fmod()"
using namespace std;
float uniform(){
// A sequence of initial values
static int x = 5;
static int y = 11;
static int z = 17;
// Some integer arithmetic required
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
/* If both operands are nonnegative then the
remainder is nonnegative; if not, the sign of
the remainder is implementation-defined. */
if(x < 0)
x = x + 30269;
if(y < 0)
y = y + 30307;
if(z < 0)
z = z + 30323;
return fmod(x / 30269. + y / 30307. + z / 30323., 1.);
}
int main(){
// Print 5 random numbers
for(int i = 0; i < 5; i++){
cout << uniform() << ", ";
}
}///:~
程序以代码退出并输出以下内容:
0.686912, 0.329174, 0.689649, 0.753722, 0.209394,
我在 R 中也有一个程序,如下所示:
## Generate pseudo random numbers uniformly between 0 and 1
uniform <- local({
# A sequence of initial values
x = 5
y = 11
z = 17
# Use the <<- operator to make x, y and z local static
# variables in R.
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x / 177)
y <<- 172 * (y %% 176) - 35 * (y / 176)
z <<- 170 * (z %% 178) - 63 * (z / 178)
return((x / 30269. + y / 30307. + z / 30323.)%%1.)
}
})
# Print 5 random numbers
for(i in 1:5){
print(uniform())
}
该程序也以代码退出并产生输出
[1] 0.1857093
[1] 0.7222047
[1] 0.05103441
[1] 0.7375034
[1] 0.2065817
任何建议表示赞赏,在此先感谢。