문제

나는 Dunit의 일부 통화 값을 비교하고 있지만 내 컴퓨터에서 전혀 작동하지 않습니다 (다른 사람과는 다르지만 내 것은 아닙니다).

An example:

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 비트 정수입니다. 아마도 추가 요청의 근거 일 것입니다 CheckEquals 이를 고려한 Dunit의 과부하.

다른 팁

Delphi 2007 Dunit 소스에는 확장 값에 대한 Checkequals () 만 있습니다. 그러나 당신은 이것을 사용할 수 있습니다 :

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

통화 값에 적절한 델타를 제공합니다.

나는 똑같은 문제를 겪었다. 일부 DLLS가 FPU (프로세서) 제어 단어를 수정하는 것처럼 보입니다. 이것은 오류가 항상 발생하지 않는 이유를 설명합니다. 이전 테스트 스위트보다 다른 장치를 사용하는 일부 새로운 테스트가 추가되면 갑자기 나타날 수 있습니다. 또는 소프트웨어 업데이트가 잘못된 DLL을 설치하는 경우. 내 블로그에 글을 썼습니다.

또한 Delphi에는 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