简体   繁体   English

C ++-g ++将int转换为double会给出负值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM