C++ - g++将 int 转换为 double 给出负值
在 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 */
刚刚注意到(math.h的)双重包含,但这不应该是问题
Was working on a project with mingw on windows :
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 :
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 :
#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 */
just noticed the double include (of math.h) but this shouldn't be an issue
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的情况下,
RAND_MAX
是存储它的整数类型的最大值,因此RAND_MAX + 1
为您提供最大负值。从技术上讲,这是有符号整数溢出,这是未定义的行为,因此任何事情都可能发生。正如 J-16 指出的那样,你需要这样做:
In your case,
RAND_MAX
is the maximum value for the integer type it is stored in, soRAND_MAX + 1
gives you the maximum negative value. Technically this is signed integer overflow which is undefined behaviour so anything can happen.You need to do, as J-16 pointed out,
在您的环境中,
RAND_MAX
可能设置为最大正数,例如0x7fff
(32767)。当您向其添加 1 时,它实际上会返回到最小的负数,例如0x8000
(-32768)。当然,这一切都假设二进制补码,并且数字将换行,这两者都不是标准所强制的)。因此,由于您将
rand
中的正值或零值除以负值,因此大多数情况下您会得到负数,偶尔也会得到零。您可以在除法中使用
RAND_MAX
而不是RAND_MAX+1
。这将避免给你一个负数,但随后你会遇到另一个问题。由于
rand
有可能返回RAND_MAX
,因此除法的结果可能为 1。然后当您尝试计算log(1 - 小数)* (-T)
,即取零的对数,最终会出现错误:log(0)
未在数学中定义。我建议通过使用类似这样的方法来简单地避免这个问题:
这将避免边缘情况,但代价是偶尔重复调用
rand
。In your environment,
RAND_MAX
is probably set to the highest positive number, such as0x7fff
(32767). When you add one to that, it actually wraps around to the lowest negative number, such as0x8000
(-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.You can use
RAND_MAX
in the division instead ofRAND_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 returnRAND_MAX
, the division may give you a result of 1. When you then try to calculatelog (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.I would suggest simply avoiding that problem by using something like this:
This will avoid the edge cases at the cost of the occasional double call to
rand
.