Bruce Dawson에 의해 제안 된 것과 같이 AlmostEqual2sComplement가 구현되었지만, float 값 대신 double을 비교했습니다.AlmostEqual2sComplement 구현이 축퇴 된 사례를 처리하지 않음
비슷한 구현체가 여러 곳에서 발견 될 수 있습니다.
bool AlmostEqual2sComplement(double A, double B, int maxUlps= 10)
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
// assert maxUlps > 0 && maxUlps < 4 * 1024 * 1024;
long long aInt = *(long long*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
aInt = 0x8000000000000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
long long bInt = *(long long*)&B;
if (bInt < 0)
bInt = 0x8000000000000000 - bInt;
long long intDiff = aInt - bInt;
if (intDiff < 0)
intDiff= intDiff*-1;
if (intDiff <= maxUlps)
return true;
return false;
}
불행히도 double 값 -1.0과 4.0을 비교하면 함수는 true를 반환합니다. 이 경우 intDiff 결과 0x8000000000000000
및 가 0x8000000000000000
의 절대치가 0x8000000000000000
이 문제 나의 현재 용액 intDiff의 절대 값을 취 아니라 intDiff의을 비교 한 변경 아니다 다시 인 동일하게 때문에 이다 과에 maxUlps :
if (intDiff <= maxUlps && -maxUlps <= intDiff)
return true;
더 (어쩌면 그렇게 분명하지 않음)의 경우이 있어야 어디 0x8000000000000000
에서 intDiff 결과.
AlmostEqual2sComplement의 다른 구현이이 문제를 인식하지 못하거나 원래 구현에서 실수를했다면 궁금합니다.
고맙습니다. 이것은 문제를 해결합니다! aInt와 bInt가 동일한 경우 intDiff는 언더 플로우를 생성 할 수 없으므로 –