2015-09-25 24 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

請讓我知道我的帖子出了什麼問題。我剛開始學習C編程。 – 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通常是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_MININT_MAX打擾,因爲這填補了一個int直接;隨機產生的溢出位溢出並被丟棄。

+0

INT_MAX - INT_MIN + 1ULL'會更乾淨,因爲不需要強制轉換 –

+0

OOC,這個標準實際上是否保證它會被評估如果'INT_MAX - INT_MIN'首先被計算,那麼你已經溢出了,我知道擴展溢出計算中涉及的左邊的值是可行的,但是我不確定擴展'1'是不是會調用im具體行爲。 – ShadowRanger

+0

在相同的表達式中,無論按照什麼順序對 –

0

INT_MAX - INT_MIN + 1int溢出並因此未定義的行爲。

您的系統遇到的行爲是除以0,因爲這通常是(雖然未指定),結果爲INT_MAX - INT_MIN + 10

rand()生成範圍爲[0...RAND_MAX]int。由於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。

+0

我創建了一個自定義公式,最後我能夠在INT_MAX和INT_MIN之間生成正數和負數的數字。 :)感謝您的建議。他們對我來說真的很寶貴! :) – user2285161

+0

隨機函數有很多陷阱。建議在這裏發佈您的解決方案作爲答案或在'http:// codereview.stackexchange.com'上查看 – chux