2013-07-12 39 views
16

如果已經回答了此問題,請道歉。srand(time(null))會導致編譯器警告:隱式轉換失去整數精度

#include <iostream> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 

int main() { 

srand(time(NULL)); 
cout << rand(); 
} 

「的隱式轉換失去整數精度:‘time_t的’(亦稱‘長’),以‘無符號整型’」

是錯誤消息時,我執行上面的代碼即時得到。我正在使用xcode 4.6.1。現在,當我使用不同的編譯器,如來自codepad.org的編譯器時,它會執行完美的生成似乎是隨機數的東西,所以我認爲這是一個需要解決的xcode問題?

我只是開始編程,所以我是一個完整的初學者,當談到這一點。我的代碼有問題還是我的編譯器?

任何幫助,將不勝感激!

+1

它的情況並不少見渴望比unsigneds更精確。 – PlasmaHH

回答

25

「隱式轉換損失整數精度:‘time_t的’(又名「長「),以‘無符號整型’」

你失去隱精度,因爲time()返回long比你的目標的unsigned int大。爲了解決這個問題,你應該明確地把結果(從而消除了「隱精度損失」):

srand(static_cast<unsigned int>(time(NULL))); 

考慮到它現在2017年,我編輯了這個問題建議你將<chrono>中定義的std::chrono::*提供的功能視爲C++ 11的一部分。你最喜歡的編譯器是否提供C++ 11?如果沒有,它真的應該!

爲了得到當前的時間,你應該使用:

#include <chrono> 

void f() { 
    const std::chrono::time_point current_time = std::chrono::system_clock::now(); 
} 

我爲什麼要打擾這個時候time()作品?

IMO,只有一個理由就足夠了:清晰,明確的類型。當你在足夠大的團隊中處理大型項目時,知道所傳遞的值是代表時間間隔還是「絕對」時間,以及什麼樣的量級至關重要。通過std::chrono,您可以設計可移植的接口和數據結構,並且可以跳過即將到期或即將到期或即將發生藍屏的最後期限或毫秒超時。

+5

由於這個問題被標記爲C++:_請不要使用C風格的強制轉換。 'srand(static_cast (time(NULL));'工作得很好,並且讓你的代碼看起來非常漂亮有光澤,作爲獎勵,它避免了大量潛在的錯誤,這些錯誤可以通過C風格的演員發揮。 .. – ComicSansMS

+1

事實上,我不小心認爲這是一個C問題,而沒有看標籤。Answer已編輯來糾正這個問題。 –

+1

它可能使用了一個不同的目標,其中一個目標是'long'和'unsigned int'(另一個編譯器是用於32位機器的,這個可能是64位的) –

4

srand函數將unsigned int作爲參數類型,time_t是long類型。從長的高4個字節被刪除,但沒有問題。 srand將用4個較低字節的時間隨機化rand算法,所以你提供的數據比需要的要多。

,如果你得到一個錯誤,儘量只顯式轉換time_t的類型unsigned int類型:

srand((unsigned int) time(NULL)); 

另一個有趣的事情是,如果你在同一秒運行你的程序兩次,你會得到相同的隨機數,這可能有時是不受歡迎的,這是因爲如果您將rand算法與相同的數據相結合,它將生成相同的隨機序列。或者,也可以是理想的,當你調試一些代碼段,需要再次測試相同的行爲......那麼你只需使用類似srand(123456)

2

這是不是出錯。代碼是有效的,它的含義是明確的;如果編譯器拒絕編譯它,編譯器不符合語言定義。更可能的是,它是警告,它告訴你編譯器作者認爲你可能犯了一個錯誤。如果你堅持要消除警告信息,你可以像其他人所建議的那樣添加一個演員陣容。爲了滿足一些編譯器作者的良好風格的概念,我並不喜歡重寫有效且有意義的代碼;我會關掉警告。但是,如果您這樣做,您可能會忽視轉換丟失了您不想要的數據的其他地方。

+0

僅僅因爲技術上正確的東西並不意味着它是一個好主意。在這種情況下,我更喜歡關閉一個編譯器警告,這可能會在你更加粗心的時候保存你的培根 –

+0

@MarkRansom - 你是否會在一個平臺上刪除'time_t'和'無符號'是相同的大小,因爲演員的原因不再適用?也許基於平臺的條件,它?追逐警告可能是一個無底洞。 –

+0

我當然不會調整這樣的演員陣容,如果我需要支持多個平臺,我不會刪除它。我現在可以看到它,但是將來有一天有人會來到StackOverflow並詢問「爲什麼這些東西在沒有做任何事情時投在這裏?」 –

13

正如「nio」所提到的,一個乾淨的解決方法是明確地鍵入強制轉換。

更深的解釋:

的srand()函數需要一個unsigned int作爲參數(srand(unsigned int)),但時間()返回一個長整型(long int time()),這不是由函數srand接受(),因此,爲了爲了解決這個問題,編譯器必須簡單地將「long int」轉換(轉換)爲「unsigned int」。 (編譯器的設計者認爲你應該意識到這一切)。編譯器的設計者認爲你應該知道這一切。

因此,一個簡單

srand((unsigned int) time(NULL));

會做的伎倆!

(原諒我,如果我做錯了什麼,這是我的第一個計算器的答案)

+1

偉大的第一個答案! –

0
#include <stdlib.h> 
#include <iostream>   //rand 
#include <time.h>  //time 

float randomizer(int VarMin, int VarMax){ 
    srand((unsigned)time(NULL)); 
     int range = (VarMax - VarMin); 
     float rnd = VarMin + float(range*(rand()/(RAND_MAX + 1.0))); 
return rnd; 
} 
+0

我如何定製此函數以微秒生成隨機數?用「srand((無符號)時間(NULL))」,這是不可能的!解決辦法是什麼? – BlueBit

+0

您可以使用像gettimeofday或GetSystemTimeAsFileTime這樣的特定於平臺的功能以亞秒精度返回時間。 – dan04

相關問題