2009-01-28 28 views
7

我比較了DUnit中的一些貨幣值,但它在我的機器上工作(在別人上工作,但不在我的工作上)。將DUnit CheckEquals中的問題與貨幣字段值進行比較

一個例子:

CheckEquals(16.65, SomeCurrencyFieldValue); 

舉:

expected: <16,65> but was: <16,65> 

如果做以下對比即可工作:

var 
    Temp: Currency; 
begin 
    Temp := 16.65; 
    CheckEquals(Temp, SomeCurrencyFieldValue); 

的問題是:爲什麼比較不在將值直接傳遞給CheckEquals方法時工作?

回答

5

該問題與運行時值如何轉換爲Extended值與編譯時浮點文字如何轉換爲Extended值的方式有關。如果兩種情況下的轉換都不相同,那麼傳遞給CheckEquals的值可能不會相等。

在調試器的CPU窗口中檢查是否有值中的任何一個值在通過Extended的途中經過中間值Double準備函數調用。額外的轉換會影響結果的確切值。

另一個要考慮的是,16.65不能準確地表示爲Extended價值,但它表示的正是作爲Currency值。儘管Currency被分類爲浮點類型,但它確實是一個定點縮放的64位整數。這可能是在DUnit中請求額外的CheckEquals過載的理由,因爲這會將此考慮在內。

+0

它爲什麼在其他一些機器上工作? – mjn 2010-11-10 07:05:51

1

我看到只有CheckEquals()用於Delphi 2007 dUnit源代碼中的擴展值。但你可以使用這一個:

procedure CheckEquals(expected, actual: extended; delta: extended; 
    msg: string = ''); overload; virtual; 

並給出貨幣值適當的三角洲。

+0

不,無效的類型轉換。 – 2009-01-28 18:37:28

1

我遇到了同樣的問題。它看起來像一些DLL修改FPU(處理器)控制字。這解釋了爲什麼錯誤不會總是發生。當添加使用除先前測試套件之外的其他單元的新測試時,它會突然出現。或者如果軟件更新安裝錯誤的DLL。我已經寫在我的博客:

我還發現,德爾福包含SafeLoadLibrary功能,恢復控制字。

這也解釋了爲什麼原始問題提到問題是機器相關的。

-1

這裏是一個建議的解決方案:

procedure CheckEquals(expected, actual: double; Precision:integer; msg:string ='');overload;virtual; 

...

procedure TAbstractTest.CheckEquals(expected, actual: double; 
    Precision: integer; msg: string); 
var 
    I: Integer; 
begin 
    FCheckCalled := true; 
    for I := 0 to Precision do begin 
    Expected := Expected * 10; 
    Actual := Actual * 10; 
    end; 
    if Round(Expected) <> Round(Actual) then 
    FailNotEquals(IntToStr(Round(Expected)), IntToStr(Round(Actual)), msg, CallerAddr); 
end; 

我知道它不好實現,但只是一個想法,我更喜歡的,然後「增量」,並更容易使用。

在DUNIT的當前版本可以使用

procedure CheckEquals(expected, actual: extended; delta: extended; msg: string = ''); overload; virtual; 
CheckEquals(0.011,0.01,0.009,'will pass'); 
相關問題