2015-09-25 3 views
-4

Ну, я чувствую, что мой вопрос немного сложнее по сравнению с другими вопросами. Я понял это, пытаясь его решить.Случайное число между INT_MAX & INT_MIN

Я попытался с помощью

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

Пожалуйста, дайте мне знать, что не так с моим сообщением. Я только начал изучать программирование на С. – user2285161

+0

Возможный дубликат [Как сгенерировать случайное число из диапазона] (http://stackoverflow.com/questions/2509679/how-to-generate-a-random-number-from-within-a-range) – John3136

+1

Две проблемы с вашей записью: 1. Ответ легко найти с помощью простого поиска Google. 2. ОБРАЩЕНИЕ В НАЗВАНИИ. – John3136

ответ

1

(INT_MAX - INT_MIN + 1), вероятно, будет переполняться (поскольку это int литералов) и произвести 0, объясняя вашу ошибку (вы делите на 0).

Переход к ((long)INT_MAX - INT_MIN + 1) бы избежать переполнения (при условии, long больше, чем int, который не относится к Visual Studio на Windows, где вы должны бросить в long long).

Это значит, что вы не получите желаемых результатов с помощью одного звонка rand; он производит только числа от 0 до RAND_MAX; RAND_MAX, как правило, 32767, поэтому в большинстве систем вы получите только тривиальную часть возможного диапазона для int (где int обычно составляет 32 бита).

Для выполнения этой работы вам нужно создать достаточное количество бит для заполнения 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 непосредственно; избыточные бит случайного генерируемого переполнения и отбрасываются.

+0

'INT_MAX - INT_MIN + 1ULL' будет более чистым, так как не требуется никакого заливки –

+0

OOC, действительно ли стандарт гарантирует, что он будет оцениваться в этом Если «INT_MAX - INT_MIN» оценивается первым, вы уже переполнились. Я знаю, что расширение значения левой стороны, участвующего в переполняющем вычислении, будет работать, но я не уверен, что расширение '1' не вызовет им специфическое поведение. – ShadowRanger

+0

В том же выражении общий тип будет использоваться независимо от того, какой порядок он оценивается в –

0

INT_MAX - INT_MIN + 1int переполнение и, следовательно, неопределенное поведение.

Поведение, которое испытывала ваша система, было делением на 0, поскольку это часто, хотя и не указано, результат INT_MAX - INT_MIN + 1 ->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; 
} 

Это технически может привести к UB редких машин, которые имеют значение ловушки для int.

+0

Я создал пользовательскую формулу и, наконец, я могу сгенерировать число как положительное, так и отрицательное между INT_MAX и INT_MIN. :) Спасибо за предложения. Они действительно такие драгоценные для меня! :) – user2285161

+0

Случайные функции имеют много подводных камней. Предложите опубликовать свое решение здесь в качестве ответа или для просмотра на 'http: // codereview.stackexchange.com' – chux

Смежные вопросы