2012-07-05 60 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