2017-07-25 180 views
-3

我想設置使用GetTickCount德爾福GetTickCount的是不是一個有效的整數

一個唯一的ID我做了以下

var 
UniqueID : DWORD; 
LastUniqueID : DWORD; 
uniqueString : string; 
begin 

UniqueID := GetTickCount; 
LastUniqueID := GetTickCount + 1000; 

uniqueString := intTostr(LastUniqueID);//or UniqueID 

end; 

我對uniqueString := intTostr(LastUniqueID);

項目得到無效的整數值project1.exe引發異常類EConvertError,消息 ''2312357250'不是有效的整數值'。

我做錯了什麼?

+4

我日後敦促您確保您發佈的代碼與您報告的錯誤相匹配。你沒有設法在這裏做到這一點。請養成張貼你已驗證的[mcve]的習慣。您發佈的代碼與錯誤消息不符的事實表明缺乏清晰的思想,這是您進步和發展的根本障礙。當你遇到問題時,慢下來思考。在跳到結論之前清楚你的事實。改善你的思維模式將帶來收益。 –

+2

如果你需要一個唯一的ID,爲什麼不使用['CreatGUID'](http://docwiki.embarcadero.com/Libraries/en/System.SysUtils.CreateGUID)? –

+0

@DavidHeffernan電力被切斷。我忘了補充一點,我再次將uniquestring轉換爲整數。你的答案清除使用int64幫助我感謝你。 –

回答

11

不幸的是,您顯示的代碼與您報告的錯誤消息不匹配。您的實際代碼請撥打StrToInt而不是IntToStr。我知道這是因爲該錯誤消息是通過調用StrToInt而不是IntToStr產生的。

你的代碼看起來更象這樣:

UniqueID := StrToInt('2312357250'); 

注意StrToInt返回32位有符號整數類型。有效值範圍在-2,147,483,648至2,147,483,647之間。您的值超出Integer的有效範圍,因此是錯誤。

如果你想要一個簡單的方法來旁路所有這些範圍問題,然後使用Int64而不是DWORDInteger,並呼籲StrToInt64

此外,這些線是麻煩:

UniqueID := GetTickCount; 
LastUniqueID := GetTickCount + 1000; 

你讓兩個不同的調用GetTickCount。這兩個調用可能會產生不同的值。實際上,如果GetTickCount翻轉,則第二個調用可能會返回一個小於第一個值的值。

還有更多的麻煩圍繞GetTickCount + 1000。如果GetTickCount返回一個接近上限的值,那麼您將遇到整數溢出,這可能會導致您不期望的結果。使用GetTickCount64來避免這個陷阱。

但是,我仍然堅信系統滴答計數可以是生成唯一ID的好方法。根據您的要求,這可能是您的問題很糟糕的解決方案,無論它是什麼。從表面上看,你的代碼似乎排除了請求一個比上次請求更晚的唯一ID。當然,如果不知道您的要求,很難推薦替代品。

+0

我不確定這是否是錯誤的原因,尤其是因爲我無法在這裏重現它。對IntToStr的調用使用Int64重載,因此在提供DWord值時不會因EConvertError而失敗。 –

+0

@Uwe你是對的。事實上,我被提問者提供的與錯誤消息不匹配的代碼欺騙了。他們實際上正在調用'StrToInt'。謝謝。 –

+0

通過在'UInt64'中使用['GetTickCount64()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411.aspx),可以避免溢出問題。 –

1

問題是2312357250太大。雖然它作爲DWORD有效,但十六進制表示89D3C582相當於DWORD無法表示的負數,因此是消息。

+2

作爲DWORD有效但DWORD無法表示?這些答案感覺不對。 – Fritzw

+1

沒有負的DWORD,十六進制表示可能是負數的整數,而不是DWORD。 –