2012-07-05 85 views
3

在德爾福如何檢測Int64的溢出錯誤?德爾福 - 檢測Int64溢出錯誤

對於整數我們可以這樣做:

type 
MyInt = Integer; //Int64 

function TryMaxTimes10(out Res: MyInt): boolean; 
var 
    a, b: MyInt; 
begin 
    {$Q+} 
    try 
    a := High(MyInt); 
    b := 10; 
    Res := a * b; //REF1 
    Result := True; 
    except 
    Result := False; 
    end; 
    {$Q-} 
end; 

對於MyInt = Integer,線REF1給出了一個例外,因此TryMaxTimes10回報false

但是,如果我們將MyInt更改爲MyInt = Int64,那麼REF1不會例外,並且TryMaxTimes10返回true

我明白,{$Q+}幫助沒有具體提及Int64:... {$Q+} state, certain integer arithmetic operations ... are checked for overflow

問題:所以我的問題是,我們如何檢測Int64的溢出錯誤?

(我用Delphi 7做同樣的事情在Delphi的新版本出現?)

+0

正在進一步調查中似乎有在__llmulo(system.pas)的錯誤。 – mas 2012-07-05 13:43:39

+0

我在這裏找到了一種(有點)解決方法:http://qc.embarcadero.com/wc/qcmain.aspx?d=34049,我可以使用類似的Fastcode來修補__llmulo。問題是,解決方法代碼可能包含錯誤(請參閱QA頁面中的進一步註釋)。有人有睾丸/工作__llmulo? – mas 2012-07-05 20:21:25

回答

3

這是一個已知的問題。見http://qc.embarcadero.com/wc/qcmain.aspx?d=10185,以及Andy在底部寫下的評論。

我的建議是建立一個功能(我沒有編制,也沒有測試此 - 只是一個例子):

function Foo(A, B : Int64) : Int64; 
var bNeg : boolean; 
begin 
    // Do we expect a negative result? 
    bNeg := ((a < 0) xor (b < 0)); 
    // Get the real result 
    Result := a * b; 
    // If the result is wrong, raise an error 
    if ((Result < 0) xor bNeg) then begin 
    // Raise EOverFlow 
    end; 
end; 
+0

謝謝保羅。通過調用上面的乘法函數很難替換所有*。我正在尋找一個更全面的解決方案,可能會修補__llmulo(system.pas函數,用於執行Int64乘法),類似於Fastcode。 – mas 2012-07-05 13:48:48

+2

是的,這會容易得多!作爲一個供參考,我使用的是Delphi XE2,我仍然可以複製這個錯誤。當然,它在D2005中被固定下來,因此「升級你的Delphi」也不是答案。 – Paul 2012-07-05 14:17:42

+0

保羅 - 感謝您的信息。 – mas 2012-07-06 11:31:26