diff --git a/release/version.info b/release/version.info index abb84c2c7dba3e786125c39613006e8ead61d0ec..0ba9f86bb823dbe7238f6fe8f409fbf799079482 100644 --- a/release/version.info +++ b/release/version.info @@ -1,2 +1,2 @@ -2.3.2 +2.3.3 diff --git a/src/unity.c b/src/unity.c index 4a1f85e9f8b91f14c856c93990764751d48c9694..e3f8a12223b857b17a54399b6554e9076b944fbf 100644 --- a/src/unity.c +++ b/src/unity.c @@ -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); diff --git a/src/unity_internals.h b/src/unity_internals.h index 5526973cce7d292f1d6eb98b1f40ff88253b3db1..8ccd66d50082a880128b6afb41ce42a8fde04a5a 100644 --- a/src/unity_internals.h +++ b/src/unity_internals.h @@ -189,11 +189,13 @@ typedef UNITY_FLOAT_TYPE _UF; #ifndef isinf -#define isinf(n) (((1.0f / f_zero) == n) ? 1 : 0) || (((-1.0f / f_zero) == n) ? 1 : 0) -#define UNITY_FLOAT_NEEDS_ZERO +/* The value of Inf - Inf is NaN */ +#define isinf(n) (isnan((n) - (n)) && !isnan(n)) #endif #ifndef isnan +/* NaN is the only floating point value that does NOT equal itself. + * Therefore if n != n, then it is NaN. */ #define isnan(n) ((n != n) ? 1 : 0) #endif @@ -213,32 +215,38 @@ typedef UNITY_FLOAT_TYPE _UF; /* unlike FLOAT, we DON'T include by default */ #ifndef UNITY_EXCLUDE_DOUBLE -#ifndef UNITY_INCLUDE_DOUBLE -#define UNITY_EXCLUDE_DOUBLE -#endif + #ifndef UNITY_INCLUDE_DOUBLE + #define UNITY_EXCLUDE_DOUBLE + #endif #endif #ifdef UNITY_EXCLUDE_DOUBLE -/* No Floating Point Support */ -#undef UNITY_DOUBLE_PRECISION -#undef UNITY_DOUBLE_TYPE -#undef UNITY_DOUBLE_VERBOSE + /* No Floating Point Support */ + #undef UNITY_DOUBLE_PRECISION + #undef UNITY_DOUBLE_TYPE + #undef UNITY_DOUBLE_VERBOSE -#ifdef UNITY_INCLUDE_DOUBLE -#undef UNITY_INCLUDE_DOUBLE -#endif + #ifdef UNITY_INCLUDE_DOUBLE + #undef UNITY_INCLUDE_DOUBLE + #endif + + #ifdef UNITY_FLOAT_VERBOSE + typedef _UF _UD; + /* For parameter in UnityPrintFloat, double promotion required */ + #endif #else -/* Double Floating Point Support */ -#ifndef UNITY_DOUBLE_PRECISION -#define UNITY_DOUBLE_PRECISION (1e-12f) -#endif -#ifndef UNITY_DOUBLE_TYPE -#define UNITY_DOUBLE_TYPE double -#endif -typedef UNITY_DOUBLE_TYPE _UD; + /* Double Floating Point Support */ + #ifndef UNITY_DOUBLE_PRECISION + #define UNITY_DOUBLE_PRECISION (1e-12f) + #endif + + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_DOUBLE_TYPE _UD; #endif @@ -436,7 +444,7 @@ void UnityPrintNumberUnsigned(const _U_UINT number); void UnityPrintNumberHex(const _U_UINT number, const char nibbles); #ifdef UNITY_FLOAT_VERBOSE -void UnityPrintFloat(const _UF number); +void UnityPrintFloat(const _UD number); #endif /*------------------------------------------------------- diff --git a/test/tests/testunity.c b/test/tests/testunity.c index e750d792bbdd0364d2620e3ad1a1362e1107f683..a8a0d3274e8ba89cedd030d0a218e0f105793126 100644 --- a/test/tests/testunity.c +++ b/test/tests/testunity.c @@ -4,8 +4,8 @@ [Released under MIT License. Please refer to license.txt for details] ========================================== */ -#include #include "unity.h" +#include #include // Dividing by these constants produces +/- infinity. @@ -2852,14 +2852,12 @@ void testFloatsNotEqualExpectedInf(void) #endif } -void testFloatsNotEqualBothInf(void) +void testFloatsEqualBothInf(void) { #ifdef UNITY_EXCLUDE_FLOAT TEST_IGNORE(); #else - EXPECT_ABORT_BEGIN TEST_ASSERT_EQUAL_FLOAT(1.0f / f_zero, 1.0f / f_zero); - VERIFY_FAILS_END #endif } @@ -3208,7 +3206,7 @@ void testNotEqualFloatArraysNaN(void) #endif } -void testNotEqualFloatArraysInf(void) +void testEqualFloatArraysInf(void) { #ifdef UNITY_EXCLUDE_FLOAT TEST_IGNORE(); @@ -3216,9 +3214,7 @@ void testNotEqualFloatArraysInf(void) float p0[] = {1.0f, 1.0f / f_zero, 25.4f, 0.253f}; float p1[] = {1.0f, 1.0f / f_zero, 25.4f, 0.253f}; - EXPECT_ABORT_BEGIN TEST_ASSERT_EQUAL_FLOAT_ARRAY(p0, p1, 4); - VERIFY_FAILS_END #endif } @@ -3384,14 +3380,12 @@ void testDoublesNotEqualExpectedInf(void) #endif } -void testDoublesNotEqualBothInf(void) +void testDoublesEqualBothInf(void) { #ifdef UNITY_EXCLUDE_DOUBLE TEST_IGNORE(); #else - EXPECT_ABORT_BEGIN TEST_ASSERT_EQUAL_DOUBLE(1.0 / d_zero, 1.0 / d_zero); - VERIFY_FAILS_END #endif } @@ -3739,7 +3733,7 @@ void testNotEqualDoubleArraysNaN(void) #endif } -void testNotEqualDoubleArraysInf(void) +void testEqualDoubleArraysInf(void) { #ifdef UNITY_EXCLUDE_DOUBLE TEST_IGNORE(); @@ -3747,9 +3741,7 @@ void testNotEqualDoubleArraysInf(void) double p0[] = {1.0, 1.0 / d_zero, 25.4, 0.253}; double p1[] = {1.0, 1.0 / d_zero, 25.4, 0.253}; - EXPECT_ABORT_BEGIN TEST_ASSERT_EQUAL_DOUBLE_ARRAY(p0, p1, 4); - VERIFY_FAILS_END #endif }