INT_MAX&之间的随机数INT_MIN

时间:2015-09-25 02:29:11

标签: c random

与其他问题相比,我觉得我的问题有点复杂。 我在尝试解决它时意识到了这一点。

我尝试使用

int number = rand() % (INT_MAX - INT_MIN + 1) + INT_MIN;
rand() % (INT_MAX + INT_MIN + 1) + rand() % INT_MIN;

但是,我得到了浮点异常8错误。没有警告,这真的很奇怪!

此外,从time.h开始,每次执行代码时,我都会使用srand((unsigned)time(NULL))作为新的随机数。

但无论我尝试什么,我都会得到不正确的结果或浮点异常。

我真的很好奇溢出&下溢,它是如何发生的 可以实际产生这样一个随机数吗?

我基本上想要生成C大于INT_MIN且小于INT_MAX的数字。

我尝试了很多逻辑,但结果不正确。

2 个答案:

答案 0 :(得分:1)

(INT_MAX - INT_MIN + 1)可能会溢出(因为他们需要int文字)并生成0,解释您的错误(您将除以0)。

更改为((long)INT_MAX - INT_MIN + 1)可以避免溢出(假设long大于int,而Windows上的Visual Studio则不是这样,您需要进行转换到long long)。

那就是说,你不会通过一次rand电话获得你想要的结果;它只产生0到RAND_MAX之间的数字; RAND_MAX通常为32767,因此您在大多数系统上(int通常为32位)只会覆盖int可能范围的一小部分。

为了完成这项工作,您需要生成足够的位来填充int。类似的东西:

#include <stdlib.h>
#include <limits.h>
#include <math.h>

/* Assumes srand() has been called with an appropriate seed at some point
   Code assumes C99 is available; minor tweaks needed for older compilers.
 */
int gen_random_int() {
    const int BITS_PER_RAND = (int)(log2(RAND_MAX/2 + 1) + 1.0); /* Or log(RAND_MAX + 1) / log(2) with older language standards */
    int ret = 0;
    for (int i = 0; i < sizeof(int) * CHAR_BIT; i += BITS_PER_RAND) {
        ret <<= BITS_PER_RAND;
        ret |= rand();
    }
    return ret;
}

您甚至不需要为INT_MININT_MAX而烦恼,因为这会直接填写int;随机生成的多余比特溢出并被丢弃。

答案 1 :(得分:1)

INT_MAX - INT_MIN + 1溢出int因此未定义行为。

您的系统所经历的行为除以0,因为INT_MAX - INT_MIN + 1 - &gt;的结果通常(尽管未指定)。 0

rand()int范围内生成[0...RAND_MAX]。自RAND_MAX <= INT_MAX起,可能需要多次调用才能在int范围内构建[0...INT_MAX],更不用说[INT_MIN...INT_MAX]了。

以下是一般方法。对于各种类型而言,它不是高效但简单且明显可修改的。

int rand_int(void) {
  union {
    int i;
    unsigned char uc[sizeof (int)];
  } u;
  for (size_t i = 0; i < sizeof u.uc; i++) {
    u.uc[i] = rand();
  }
  return u.i;
}

技术上,它可以在具有int陷阱值的稀有机器上导致UB。