[英]C++ - g++ casting int to double gives negative value
Was working on a project with mingw on windows : 正在使用Windows上的mingw进行项目:
C:\Users\...>g++ -dumpversion
4.5.0
When I compiled the code under g++ v 4.2.4 I was getting a segmentation fault - after couple hours I pinned it down to the line : 当我在g ++ v 4.2.4下编译代码时,遇到了分段错误-几个小时后,我将其固定在该行上:
double decimal = ((double) rand()) / (RAND_MAX + 1);
For some reason this was giving negative values (and one thing led to another). 由于某种原因,这给了负值(一件事导致了另一件事)。 What reason ?
什么理由 ?
Edit : cpp : 编辑: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: 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 */
just noticed the double include (of math.h) but this shouldn't be an issue 刚刚注意到(math.h)的双重包含,但这不应该成为问题
In your case, RAND_MAX
is the maximum value for the integer type it is stored in, so RAND_MAX + 1
gives you the maximum negative value. 在您的情况下,
RAND_MAX
是其存储的整数类型的最大值,因此RAND_MAX + 1
为您提供最大负值。 Technically this is signed integer overflow which is undefined behaviour so anything can happen. 从技术上讲,这是有符号整数溢出,这是未定义的行为,因此任何事情都可能发生。
You need to do, as J-16 pointed out, 正如J-16所指出的,您需要做的是,
double decimal = (double)rand() / ((double)RAND_MAX + 1);
In your environment, RAND_MAX
is probably set to the highest positive number, such as 0x7fff
(32767). 在您的环境中,
RAND_MAX
可能设置为最高正数,例如0x7fff
(32767)。 When you add one to that, it actually wraps around to the lowest negative number, such as 0x8000
(-32768). 当您向其添加一个时,它实际上会换成最低的负数,例如
0x8000
(-32768)。 This all assumes two's complement of course and that the number will wrap, neither of which are mandated by the standard). 当然,所有这些都假定为二进制补码,并且该数字将自动包装,而标准均未要求这两个数字。
So, because you're dividing the positive-or-zero value from rand
by a negative value, you'll end up with a negative number most of the time, and zero occasionally. 因此,由于您要将
rand
的正值或零值除以负值,因此大多数情况下最终会得到负数,偶尔会为零。
You can use RAND_MAX
in the division instead of RAND_MAX+1
. 您可以在分区中使用
RAND_MAX
而不是RAND_MAX+1
。 This will avoid giving you a negative number but then you'll run into another problem. 这样可以避免给您一个负数,但是会遇到另一个问题。
Because there's a possibility that rand
will return RAND_MAX
, the division may give you a result of 1. When you then try to calculate log (1 - decimal) * (-T)
, that's taking the logarithm of zero and you'll end up with an error: log(0)
is not defined in mathematics. 因为
rand
可能返回RAND_MAX
,所以除法可能会为您提供1的结果。当您尝试计算log (1 - decimal) * (-T)
,将取对数零,最终错误: log(0)
在数学中未定义。
I would suggest simply avoiding that problem by using something like this: 我建议您通过使用以下方法来避免该问题:
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);
}
This will avoid the edge cases at the cost of the occasional double call to rand
. 这样可以避免偶尔出现对
rand
两次调用,从而避免了出现极端情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.