Frage

Ich habe einige Währungswerte in DUnit zu vergleichen, aber es ist überhaupt nicht auf meinem Rechner arbeitet (Arbeit auf anderen, aber nicht auf mich).

Ein Beispiel:

CheckEquals(16.65, SomeCurrencyFieldValue);

Hebt:

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

, wenn die nach dem Vergleich tut dann funktioniert:

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

Die Frage ist: Warum der Vergleich nicht, wenn ich den Wert direkt an die CheckEquals Methode übergeben

War es hilfreich?

Lösung

Das Problem hat mit, wie Currency Werten zu tun bekommen gewandelten Werte zur Laufzeit im Vergleich zu Extended wie Gleitpunktliterale konvertiert werden Werten bei der Kompilierung Extended. Wenn die Umwandlung nicht die in beiden Fällen gleich ist, dann sind die zu CheckEquals gebenen Werte nicht gleich vergleichen.

Es würde sich lohnen, in dem Debugger Fenster CPU überprüft, ob eine der beiden Werte durch einen Zwischen Double Wert auf seinem Weg geht in der Vorbereitung für den Funktionsaufruf Extended. Eine zusätzliche Umwandlung, den genauen Wert des Ergebnisses beeinflussen würde.

Eine andere Sache zu prüfen ist, dass 16,65 nicht genau darstellbar als Extended Wert, aber es ist darstellbare genau als Currency Wert. Obwohl Currency als Fließkommatyp klassifiziert wird, ist es wirklich ein Festpunkt-skalierten ganzzahligen 64-Bit. Das ist wahrscheinlich ein Grund für eine zusätzliche CheckEquals Überlastung in DUnit anfordert, die berücksichtigt, dass.

Andere Tipps

Ich sehe, dass es nur CheckEquals ist () für längere Werte in den Delphi 2007 dunit Quellen. Aber man könnte diese verwenden:

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

und gibt eine richtige Delta für Währungswerte.

Ich traf das gleiche Problem. Es sieht aus wie einige DLLs eine FPU (Prozessor) Steuerwort ändern. Dies erklärt, warum tritt der Fehler nicht immer auftreten. Es kann plötzlich auftreten, wenn einige neue Tests, die anderen Einheiten als der vorherige Test-Suite verwenden, hinzugefügt werden. Oder wenn eine Software-Update installiert schlechten DLLs. Ich habe auf meinem Blog darüber geschrieben:

Ich fand auch, dass Delphi eine SafeLoadLibrary Funktion enthält, die das Steuerwort wieder her.

Dies erklärt auch, warum die ursprüngliche Frage erwähnt, dass das Problem ist maschinenabhängig.

Hier ist eine vorgeschlagene Lösung:

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;

Ich weiß, dass seine schlechte Umsetzung, aber nur eine Idee, dass ich besser als „delta“ mag, und viel einfacher zu bedienen.

In der aktuellen Version von dunit können Sie

procedure CheckEquals(expected, actual: extended; delta: extended; msg: string = ''); overload; virtual;
CheckEquals(0.011,0.01,0.009,'will pass');
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top