我比较了一些币值述,但它是不是在所有工作我的机器上(工作上的其他人,但不排雷).

一个例子:

CheckEquals(16.65, SomeCurrencyFieldValue);

引发:

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

如果做下比较后,工作:

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

问题是:为什么比较不工作的时候我传递的价值直接的CheckEquals方法?

有帮助吗?

解决方案

这个问题有Currency值是如何被转换在运行时Extended的值相对于浮点文字是如何被转换在编译时Extended值做。如果转换是不在两种情况下是相同的,然后传递到CheckEquals的值可能不等于比较

这将是值得在调试器的CPU检查窗口的任一值的是否经过的道路上在对函数调用制备Double中间Extended值。一个额外的转换会影响结果的精确值。

要考虑的另一件事是,16.65并不精确表示作为Extended值,但它的可表示恰好作为Currency值。虽然Currency被分类为浮点型,它实际上是一个固定点缩放的64位整数。这可能理由要求在DUNIT额外CheckEquals重载需要一点考虑在内。

其他提示

我看到仅存在CheckEquals(),用于在Delphi 2007 DUNIT源扩展值。但是你可以用这一个:

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

和给一个适当的增量为货币值。

我遇到了同样的问题。它看起来像一些Dll修改FPU(处理器)控制个词。这就解释了为什么不会发生错误。它可能突然出现时,一些新的试验,使用其他单元比以前的测试,增加。或者如果一个软件更新安装坏Dll。我已经写在我的博客:

我还发现,德尔斐包含一个SafeLoadLibrary功能,恢复控制词。

这也解释了为什么原来的问题提到这个问题是计算机的依赖。

这里是一个建议的解决方案:

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');
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top