Skip to content

Commit 7dc17ef

Browse files
authored
Merge pull request #215 from jsalling/bugfix/inf-equals-inf
Bugfix Inf equals Inf
2 parents 71f2e0e + 41c2e58 commit 7dc17ef

File tree

4 files changed

+61
-95
lines changed

4 files changed

+61
-95
lines changed

release/version.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
2.3.2
1+
2.3.3
22

src/unity.c

Lines changed: 26 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,6 @@ static const char UnityStrResultsIgnored[] = " Ignored ";
5252
static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " ";
5353
static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " ";
5454

55-
#ifdef UNITY_FLOAT_NEEDS_ZERO
56-
/* Dividing by these constants produces +/- infinity.
57-
* The rationale is given in UnityAssertFloatIsInf's body. */
58-
static const _UF f_zero = 0.0f;
59-
#endif
60-
6155
/* compiler-generic print formatting masks */
6256
static const _U_UINT UnitySizeMask[] =
6357
{
@@ -265,7 +259,7 @@ void UnityPrintMask(const _U_UINT mask, const _U_UINT number)
265259
# endif
266260
#endif
267261

268-
void UnityPrintFloat(_UF number)
262+
void UnityPrintFloat(_UD number)
269263
{
270264
char TempBuffer[UNITY_VERBOSE_NUMBER_MAX_LENGTH + 1];
271265
snprintf(TempBuffer, sizeof(TempBuffer), "%.6f", number);
@@ -620,7 +614,22 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
620614
}
621615

622616
/*-----------------------------------------------*/
617+
/* Wrap this define in a function with variable types as float or double */
618+
#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \
619+
if (expected == actual) return 1; \
620+
diff = actual - expected; \
621+
if (diff < 0.0f) diff = 0.0f - diff; \
622+
if (delta < 0.0f) delta = 0.0f - delta; \
623+
return !(isnan(diff) || isinf(diff) || (delta < diff));
624+
/* This first part of this condition will catch any NaN or Infinite values */
625+
623626
#ifndef UNITY_EXCLUDE_FLOAT
627+
static int UnityFloatsWithin(_UF delta, _UF expected, _UF actual)
628+
{
629+
_UF diff;
630+
UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
631+
}
632+
624633
void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
625634
UNITY_PTR_ATTRIBUTE const _UF* actual,
626635
const _UU32 num_elements,
@@ -630,7 +639,6 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
630639
_UU32 elements = num_elements;
631640
UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected;
632641
UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual;
633-
_UF diff, tol;
634642

635643
UNITY_SKIP_EXECUTION;
636644

@@ -644,15 +652,7 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
644652

645653
while (elements--)
646654
{
647-
diff = *ptr_expected - *ptr_actual;
648-
if (diff < 0.0f)
649-
diff = 0.0f - diff;
650-
tol = UNITY_FLOAT_PRECISION * *ptr_expected;
651-
if (tol < 0.0f)
652-
tol = 0.0f - tol;
653-
654-
/* This first part of this condition will catch any NaN or Infinite values */
655-
if (isnan(diff) || isinf(diff) || (diff > tol))
655+
if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual))
656656
{
657657
UnityTestResultsFailBegin(lineNumber);
658658
UnityPrint(UnityStrElement);
@@ -680,22 +680,10 @@ void UnityAssertFloatsWithin(const _UF delta,
680680
const char* msg,
681681
const UNITY_LINE_TYPE lineNumber)
682682
{
683-
_UF diff = actual - expected;
684-
_UF pos_delta = delta;
685-
686683
UNITY_SKIP_EXECUTION;
687684

688-
if (diff < 0.0f)
689-
{
690-
diff = 0.0f - diff;
691-
}
692-
if (pos_delta < 0.0f)
693-
{
694-
pos_delta = 0.0f - pos_delta;
695-
}
696685

697-
/* This first part of this condition will catch any NaN or Infinite values */
698-
if (isnan(diff) || isinf(diff) || (pos_delta < diff))
686+
if (!UnityFloatsWithin(delta, expected, actual))
699687
{
700688
UnityTestResultsFailBegin(lineNumber);
701689
#ifdef UNITY_FLOAT_VERBOSE
@@ -726,8 +714,6 @@ void UnityAssertFloatSpecial(const _UF actual,
726714

727715
switch(style)
728716
{
729-
/* To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
730-
* We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise */
731717
case UNITY_FLOAT_IS_INF:
732718
case UNITY_FLOAT_IS_NOT_INF:
733719
is_trait = isinf(actual) & ispos(actual);
@@ -737,7 +723,6 @@ void UnityAssertFloatSpecial(const _UF actual,
737723
is_trait = isinf(actual) & isneg(actual);
738724
break;
739725

740-
/* NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. */
741726
case UNITY_FLOAT_IS_NAN:
742727
case UNITY_FLOAT_IS_NOT_NAN:
743728
is_trait = isnan(actual);
@@ -782,6 +767,12 @@ void UnityAssertFloatSpecial(const _UF actual,
782767

783768
/*-----------------------------------------------*/
784769
#ifndef UNITY_EXCLUDE_DOUBLE
770+
static int UnityDoublesWithin(_UD delta, _UD expected, _UD actual)
771+
{
772+
_UD diff;
773+
UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff);
774+
}
775+
785776
void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
786777
UNITY_PTR_ATTRIBUTE const _UD* actual,
787778
const _UU32 num_elements,
@@ -791,7 +782,6 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
791782
_UU32 elements = num_elements;
792783
UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected;
793784
UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual;
794-
_UD diff, tol;
795785

796786
UNITY_SKIP_EXECUTION;
797787

@@ -805,15 +795,7 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
805795

806796
while (elements--)
807797
{
808-
diff = *ptr_expected - *ptr_actual;
809-
if (diff < 0.0)
810-
diff = 0.0 - diff;
811-
tol = UNITY_DOUBLE_PRECISION * *ptr_expected;
812-
if (tol < 0.0)
813-
tol = 0.0 - tol;
814-
815-
/* This first part of this condition will catch any NaN or Infinite values */
816-
if (isnan(diff) || isinf(diff) || (diff > tol))
798+
if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual))
817799
{
818800
UnityTestResultsFailBegin(lineNumber);
819801
UnityPrint(UnityStrElement);
@@ -841,22 +823,9 @@ void UnityAssertDoublesWithin(const _UD delta,
841823
const char* msg,
842824
const UNITY_LINE_TYPE lineNumber)
843825
{
844-
_UD diff = actual - expected;
845-
_UD pos_delta = delta;
846-
847826
UNITY_SKIP_EXECUTION;
848827

849-
if (diff < 0.0)
850-
{
851-
diff = 0.0 - diff;
852-
}
853-
if (pos_delta < 0.0)
854-
{
855-
pos_delta = 0.0 - pos_delta;
856-
}
857-
858-
/* This first part of this condition will catch any NaN or Infinite values */
859-
if (isnan(diff) || isinf(diff) || (pos_delta < diff))
828+
if (!UnityDoublesWithin(delta, expected, actual))
860829
{
861830
UnityTestResultsFailBegin(lineNumber);
862831
#ifdef UNITY_DOUBLE_VERBOSE
@@ -888,8 +857,6 @@ void UnityAssertDoubleSpecial(const _UD actual,
888857

889858
switch(style)
890859
{
891-
/* To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
892-
* We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise */
893860
case UNITY_FLOAT_IS_INF:
894861
case UNITY_FLOAT_IS_NOT_INF:
895862
is_trait = isinf(actual) & ispos(actual);
@@ -899,7 +866,6 @@ void UnityAssertDoubleSpecial(const _UD actual,
899866
is_trait = isinf(actual) & isneg(actual);
900867
break;
901868

902-
/* NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. */
903869
case UNITY_FLOAT_IS_NAN:
904870
case UNITY_FLOAT_IS_NOT_NAN:
905871
is_trait = isnan(actual);

src/unity_internals.h

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,13 @@
189189
typedef UNITY_FLOAT_TYPE _UF;
190190

191191
#ifndef isinf
192-
#define isinf(n) (((1.0f / f_zero) == n) ? 1 : 0) || (((-1.0f / f_zero) == n) ? 1 : 0)
193-
#define UNITY_FLOAT_NEEDS_ZERO
192+
/* The value of Inf - Inf is NaN */
193+
#define isinf(n) (isnan((n) - (n)) && !isnan(n))
194194
#endif
195195

196196
#ifndef isnan
197+
/* NaN is the only floating point value that does NOT equal itself.
198+
* Therefore if n != n, then it is NaN. */
197199
#define isnan(n) ((n != n) ? 1 : 0)
198200
#endif
199201

@@ -213,32 +215,38 @@ typedef UNITY_FLOAT_TYPE _UF;
213215

214216
/* unlike FLOAT, we DON'T include by default */
215217
#ifndef UNITY_EXCLUDE_DOUBLE
216-
#ifndef UNITY_INCLUDE_DOUBLE
217-
#define UNITY_EXCLUDE_DOUBLE
218-
#endif
218+
#ifndef UNITY_INCLUDE_DOUBLE
219+
#define UNITY_EXCLUDE_DOUBLE
220+
#endif
219221
#endif
220222

221223
#ifdef UNITY_EXCLUDE_DOUBLE
222224

223-
/* No Floating Point Support */
224-
#undef UNITY_DOUBLE_PRECISION
225-
#undef UNITY_DOUBLE_TYPE
226-
#undef UNITY_DOUBLE_VERBOSE
225+
/* No Floating Point Support */
226+
#undef UNITY_DOUBLE_PRECISION
227+
#undef UNITY_DOUBLE_TYPE
228+
#undef UNITY_DOUBLE_VERBOSE
227229

228-
#ifdef UNITY_INCLUDE_DOUBLE
229-
#undef UNITY_INCLUDE_DOUBLE
230-
#endif
230+
#ifdef UNITY_INCLUDE_DOUBLE
231+
#undef UNITY_INCLUDE_DOUBLE
232+
#endif
233+
234+
#ifdef UNITY_FLOAT_VERBOSE
235+
typedef _UF _UD;
236+
/* For parameter in UnityPrintFloat, double promotion required */
237+
#endif
231238

232239
#else
233240

234-
/* Double Floating Point Support */
235-
#ifndef UNITY_DOUBLE_PRECISION
236-
#define UNITY_DOUBLE_PRECISION (1e-12f)
237-
#endif
238-
#ifndef UNITY_DOUBLE_TYPE
239-
#define UNITY_DOUBLE_TYPE double
240-
#endif
241-
typedef UNITY_DOUBLE_TYPE _UD;
241+
/* Double Floating Point Support */
242+
#ifndef UNITY_DOUBLE_PRECISION
243+
#define UNITY_DOUBLE_PRECISION (1e-12f)
244+
#endif
245+
246+
#ifndef UNITY_DOUBLE_TYPE
247+
#define UNITY_DOUBLE_TYPE double
248+
#endif
249+
typedef UNITY_DOUBLE_TYPE _UD;
242250

243251
#endif
244252

@@ -436,7 +444,7 @@ void UnityPrintNumberUnsigned(const _U_UINT number);
436444
void UnityPrintNumberHex(const _U_UINT number, const char nibbles);
437445

438446
#ifdef UNITY_FLOAT_VERBOSE
439-
void UnityPrintFloat(const _UF number);
447+
void UnityPrintFloat(const _UD number);
440448
#endif
441449

442450
/*-------------------------------------------------------

test/tests/testunity.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
[Released under MIT License. Please refer to license.txt for details]
55
========================================== */
66

7-
#include <setjmp.h>
87
#include "unity.h"
8+
#include <setjmp.h>
99
#include <string.h>
1010

1111
// Dividing by these constants produces +/- infinity.
@@ -2852,14 +2852,12 @@ void testFloatsNotEqualExpectedInf(void)
28522852
#endif
28532853
}
28542854

2855-
void testFloatsNotEqualBothInf(void)
2855+
void testFloatsEqualBothInf(void)
28562856
{
28572857
#ifdef UNITY_EXCLUDE_FLOAT
28582858
TEST_IGNORE();
28592859
#else
2860-
EXPECT_ABORT_BEGIN
28612860
TEST_ASSERT_EQUAL_FLOAT(1.0f / f_zero, 1.0f / f_zero);
2862-
VERIFY_FAILS_END
28632861
#endif
28642862
}
28652863

@@ -3208,17 +3206,15 @@ void testNotEqualFloatArraysNaN(void)
32083206
#endif
32093207
}
32103208

3211-
void testNotEqualFloatArraysInf(void)
3209+
void testEqualFloatArraysInf(void)
32123210
{
32133211
#ifdef UNITY_EXCLUDE_FLOAT
32143212
TEST_IGNORE();
32153213
#else
32163214
float p0[] = {1.0f, 1.0f / f_zero, 25.4f, 0.253f};
32173215
float p1[] = {1.0f, 1.0f / f_zero, 25.4f, 0.253f};
32183216

3219-
EXPECT_ABORT_BEGIN
32203217
TEST_ASSERT_EQUAL_FLOAT_ARRAY(p0, p1, 4);
3221-
VERIFY_FAILS_END
32223218
#endif
32233219
}
32243220

@@ -3384,14 +3380,12 @@ void testDoublesNotEqualExpectedInf(void)
33843380
#endif
33853381
}
33863382

3387-
void testDoublesNotEqualBothInf(void)
3383+
void testDoublesEqualBothInf(void)
33883384
{
33893385
#ifdef UNITY_EXCLUDE_DOUBLE
33903386
TEST_IGNORE();
33913387
#else
3392-
EXPECT_ABORT_BEGIN
33933388
TEST_ASSERT_EQUAL_DOUBLE(1.0 / d_zero, 1.0 / d_zero);
3394-
VERIFY_FAILS_END
33953389
#endif
33963390
}
33973391

@@ -3739,17 +3733,15 @@ void testNotEqualDoubleArraysNaN(void)
37393733
#endif
37403734
}
37413735

3742-
void testNotEqualDoubleArraysInf(void)
3736+
void testEqualDoubleArraysInf(void)
37433737
{
37443738
#ifdef UNITY_EXCLUDE_DOUBLE
37453739
TEST_IGNORE();
37463740
#else
37473741
double p0[] = {1.0, 1.0 / d_zero, 25.4, 0.253};
37483742
double p1[] = {1.0, 1.0 / d_zero, 25.4, 0.253};
37493743

3750-
EXPECT_ABORT_BEGIN
37513744
TEST_ASSERT_EQUAL_DOUBLE_ARRAY(p0, p1, 4);
3752-
VERIFY_FAILS_END
37533745
#endif
37543746
}
37553747

0 commit comments

Comments
 (0)