Merge pull request #215 from jsalling/bugfix/inf-equals-inf

Bugfix Inf equals Inf
This commit is contained in:
Mark VanderVoord
2016-09-21 20:52:58 -04:00
committed by GitHub
4 changed files with 61 additions and 95 deletions

View File

@ -52,12 +52,6 @@ static const char UnityStrResultsIgnored[] = " Ignored ";
static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " ";
static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " ";
#ifdef UNITY_FLOAT_NEEDS_ZERO
/* Dividing by these constants produces +/- infinity.
* The rationale is given in UnityAssertFloatIsInf's body. */
static const _UF f_zero = 0.0f;
#endif
/* compiler-generic print formatting masks */
static const _U_UINT UnitySizeMask[] =
{
@ -265,7 +259,7 @@ void UnityPrintMask(const _U_UINT mask, const _U_UINT number)
# endif
#endif
void UnityPrintFloat(_UF number)
void UnityPrintFloat(_UD number)
{
char TempBuffer[UNITY_VERBOSE_NUMBER_MAX_LENGTH + 1];
snprintf(TempBuffer, sizeof(TempBuffer), "%.6f", number);
@ -620,7 +614,22 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
}
/*-----------------------------------------------*/
/* Wrap this define in a function with variable types as float or double */
#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \
if (expected == actual) return 1; \
diff = actual - expected; \
if (diff < 0.0f) diff = 0.0f - diff; \
if (delta < 0.0f) delta = 0.0f - delta; \
return !(isnan(diff) || isinf(diff) || (delta < diff));
/* This first part of this condition will catch any NaN or Infinite values */
#ifndef UNITY_EXCLUDE_FLOAT
static int UnityFloatsWithin(_UF delta, _UF expected, _UF actual)
{
_UF diff;
UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
}
void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
UNITY_PTR_ATTRIBUTE const _UF* actual,
const _UU32 num_elements,
@ -630,7 +639,6 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
_UU32 elements = num_elements;
UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected;
UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual;
_UF diff, tol;
UNITY_SKIP_EXECUTION;
@ -644,15 +652,7 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
while (elements--)
{
diff = *ptr_expected - *ptr_actual;
if (diff < 0.0f)
diff = 0.0f - diff;
tol = UNITY_FLOAT_PRECISION * *ptr_expected;
if (tol < 0.0f)
tol = 0.0f - tol;
/* This first part of this condition will catch any NaN or Infinite values */
if (isnan(diff) || isinf(diff) || (diff > tol))
if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual))
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
@ -680,22 +680,10 @@ void UnityAssertFloatsWithin(const _UF delta,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UF diff = actual - expected;
_UF pos_delta = delta;
UNITY_SKIP_EXECUTION;
if (diff < 0.0f)
{
diff = 0.0f - diff;
}
if (pos_delta < 0.0f)
{
pos_delta = 0.0f - pos_delta;
}
/* This first part of this condition will catch any NaN or Infinite values */
if (isnan(diff) || isinf(diff) || (pos_delta < diff))
if (!UnityFloatsWithin(delta, expected, actual))
{
UnityTestResultsFailBegin(lineNumber);
#ifdef UNITY_FLOAT_VERBOSE
@ -726,8 +714,6 @@ void UnityAssertFloatSpecial(const _UF actual,
switch(style)
{
/* To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
* We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise */
case UNITY_FLOAT_IS_INF:
case UNITY_FLOAT_IS_NOT_INF:
is_trait = isinf(actual) & ispos(actual);
@ -737,7 +723,6 @@ void UnityAssertFloatSpecial(const _UF actual,
is_trait = isinf(actual) & isneg(actual);
break;
/* NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. */
case UNITY_FLOAT_IS_NAN:
case UNITY_FLOAT_IS_NOT_NAN:
is_trait = isnan(actual);
@ -782,6 +767,12 @@ void UnityAssertFloatSpecial(const _UF actual,
/*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_DOUBLE
static int UnityDoublesWithin(_UD delta, _UD expected, _UD actual)
{
_UD diff;
UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
}
void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
UNITY_PTR_ATTRIBUTE const _UD* actual,
const _UU32 num_elements,
@ -791,7 +782,6 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
_UU32 elements = num_elements;
UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected;
UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual;
_UD diff, tol;
UNITY_SKIP_EXECUTION;
@ -805,15 +795,7 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
while (elements--)
{
diff = *ptr_expected - *ptr_actual;
if (diff < 0.0)
diff = 0.0 - diff;
tol = UNITY_DOUBLE_PRECISION * *ptr_expected;
if (tol < 0.0)
tol = 0.0 - tol;
/* This first part of this condition will catch any NaN or Infinite values */
if (isnan(diff) || isinf(diff) || (diff > tol))
if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual))
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrElement);
@ -841,22 +823,9 @@ void UnityAssertDoublesWithin(const _UD delta,
const char* msg,
const UNITY_LINE_TYPE lineNumber)
{
_UD diff = actual - expected;
_UD pos_delta = delta;
UNITY_SKIP_EXECUTION;
if (diff < 0.0)
{
diff = 0.0 - diff;
}
if (pos_delta < 0.0)
{
pos_delta = 0.0 - pos_delta;
}
/* This first part of this condition will catch any NaN or Infinite values */
if (isnan(diff) || isinf(diff) || (pos_delta < diff))
if (!UnityDoublesWithin(delta, expected, actual))
{
UnityTestResultsFailBegin(lineNumber);
#ifdef UNITY_DOUBLE_VERBOSE
@ -888,8 +857,6 @@ void UnityAssertDoubleSpecial(const _UD actual,
switch(style)
{
/* To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
* We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise */
case UNITY_FLOAT_IS_INF:
case UNITY_FLOAT_IS_NOT_INF:
is_trait = isinf(actual) & ispos(actual);
@ -899,7 +866,6 @@ void UnityAssertDoubleSpecial(const _UD actual,
is_trait = isinf(actual) & isneg(actual);
break;
/* NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. */
case UNITY_FLOAT_IS_NAN:
case UNITY_FLOAT_IS_NOT_NAN:
is_trait = isnan(actual);