与其他问题相比,我觉得我的问题有点复杂。 我在尝试解决它时意识到了这一点。
我尝试使用
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
的数字。
我尝试了很多逻辑,但结果不正确。
答案 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_MIN
和INT_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。