正在使用Windows上的mingw项目:
C:\Users\...>g++ -dumpversion
4.5.0
当我在g ++ v 4.2.4下编译代码时,我遇到了一个分段错误 - 几个小时后我把它固定到了这一行:
double decimal = ((double) rand()) / (RAND_MAX + 1);
出于某种原因,这给了负值(有一件事导致了另一件事)。 是什么原因?
编辑:cpp:
#include <iostream>
#include "Random.h"
#include <math.h>
using namespace std;
double Random::exponential(int T) {
double decimal = ((double) rand()) / (RAND_MAX + 1);
// std::cout << "decimal : " << decimal << std::endl;
return log(1 - decimal)*(-T);
}
//etc
H:
#ifndef RANDOM_H
#define RANDOM_H
#include <cstdlib>
#include <math.h>
class Random {
public:
static double exponential(int T);
static int random_int(int min, int max);
static bool coin(); //50% true 50% false
};
#endif /* RANDOM_H */
刚刚注意到double(math.h),但这应该不是问题
答案 0 :(得分:4)
在您的情况下,RAND_MAX
是其存储的整数类型的最大值,因此RAND_MAX + 1
为您提供最大负值。从技术上讲,这是带符号的整数溢出,这是未定义的行为,因此任何事情都可能发生。
你需要这样做,正如J-16所指出的那样,
double decimal = (double)rand() / ((double)RAND_MAX + 1);
答案 1 :(得分:1)
在您的环境中,RAND_MAX
可能设置为最高正数,例如0x7fff
(32767)。当你向它添加一个时,它实际上会回绕到最低的负数,例如0x8000
( - 32768)。这一切都假定当然是两个补码,数字将包装,这两者都不是标准规定的。)
因此,因为您将正值或零值从rand
除以负值,所以大部分时间都会得到负数,偶尔也会为零。
您可以在分部中使用RAND_MAX
而不是RAND_MAX+1
。这样可以避免给你一个负数,但是你会遇到另一个问题。
因为rand
可能会返回RAND_MAX
,所以除法可能会给你1的结果。然后当你尝试计算log (1 - decimal) * (-T)
时,它的对数为零,你最终会得到一个错误:log(0)
没有在数学中定义。
我建议通过使用类似的东西来避免这个问题:
double Random::exponential (int T) {
int randVal = rand();
while (randVal == RAND_MAX)
randVal = rand();
double decimal = (double) randVal / RAND_MAX;
return log (1 - decimal) * (-T);
}
这样可以避免边缘情况,但偶尔会对rand
进行双重调用。