Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Unity
提交
b0870ec8
T
Third Party Unity
项目概览
OpenHarmony
/
Third Party Unity
1 年多 前同步成功
通知
36
Star
144
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Unity
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b0870ec8
编写于
12月 15, 2016
作者:
J
jsalling
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'feature/print-floats'
Fix new type name conflicts Conflicts: src/unity.c src/unity_internals.h
上级
8e31f5d8
aa4d773d
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
351 addition
and
73 deletion
+351
-73
src/unity.c
src/unity.c
+102
-47
src/unity.h
src/unity.h
+1
-3
src/unity_internals.h
src/unity_internals.h
+9
-12
test/tests/testunity.c
test/tests/testunity.c
+239
-11
未找到文件。
src/unity.c
浏览文件 @
b0870ec8
...
...
@@ -250,24 +250,94 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
}
/*-----------------------------------------------*/
#ifdef UNITY_FLOAT_VERBOSE
#include <stdio.h>
#ifndef UNITY_VERBOSE_NUMBER_MAX_LENGTH
# ifdef UNITY_DOUBLE_VERBOSE
# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 317
# else
# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 47
# endif
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
static
void
UnityPrintDecimalAndNumberWithLeadingZeros
(
UNITY_INT32
fraction_part
,
UNITY_INT32
divisor
)
{
UNITY_OUTPUT_CHAR
(
'.'
);
while
(
divisor
>
0
)
{
UNITY_OUTPUT_CHAR
(
'0'
+
fraction_part
/
divisor
);
fraction_part
%=
divisor
;
divisor
/=
10
;
if
(
fraction_part
==
0
)
break
;
/* Truncate trailing 0's */
}
}
#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO
/* If rounds up && remainder 0.5 && result odd && below cutoff for double precision issues */
#define ROUND_TIES_TO_EVEN(orig, num_int, num) \
if (num_int > (num) && (num) - (num_int-1) <= 0.5 && (num_int & 1) == 1 && orig < 1e22) \
num_int -= 1
/* => a tie to round down to even */
#else
#define ROUND_TIES_TO_EVEN(orig, num_int, num)
/* Remove macro */
#endif
/* Printing floating point numbers is hard. Some goals of this implementation: works for embedded
* systems, floats or doubles, and has a reasonable format. The key paper in this area,
* 'How to Print Floating-Point Numbers Accurately' by Steele & White, shows an approximation by
* scaling called Dragon 2. This code uses a similar idea. The other core algorithm uses casts and
* floating subtraction to give exact remainders after the decimal, to be scaled into an integer.
* Extra trailing 0's are excluded. The output defaults to rounding to nearest, ties to even. You
* can enable rounding ties away from zero. Note: UNITY_DOUBLE param can typedef to float or double
* The old version required compiling in snprintf. For reference, with a similar format as now:
* char buf[19];
* if (number > 4294967296.0 || -number > 4294967296.0) snprintf(buf, sizeof buf, "%.8e", number);
* else snprintf(buf, sizeof buf, "%.6f", number);
* UnityPrint(buf);
*/
void
UnityPrintFloat
(
UNITY_DOUBLE
number
)
{
char
TempBuffer
[
UNITY_VERBOSE_NUMBER_MAX_LENGTH
+
1
];
snprintf
(
TempBuffer
,
sizeof
(
TempBuffer
),
"%.6f"
,
number
);
UnityPrint
(
TempBuffer
);
if
(
number
<
0
)
{
UNITY_OUTPUT_CHAR
(
'-'
);
number
=
-
number
;
}
if
(
isnan
(
number
))
UnityPrint
(
UnityStrNaN
);
else
if
(
isinf
(
number
))
UnityPrintLen
(
UnityStrInf
,
3
);
else
if
(
number
<=
0
.
0000005
&&
number
>
0
)
UnityPrint
(
"0.000000..."
);
/* Small number */
else
if
(
number
<
4294967295
.
9999995
)
/* Rounded result fits in 32 bits, "%.6f" format */
{
const
UNITY_INT32
divisor
=
1000000
/
10
;
UNITY_UINT32
integer_part
=
(
UNITY_UINT32
)
number
;
UNITY_INT32
fraction_part
=
(
UNITY_INT32
)((
number
-
(
UNITY_DOUBLE
)
integer_part
)
*
1000000
.
0
+
0
.
5
);
/* Double precision calculation gives best performance for six rounded decimal places */
ROUND_TIES_TO_EVEN
(
number
,
fraction_part
,
(
number
-
(
UNITY_DOUBLE
)
integer_part
)
*
1000000
.
0
);
if
(
fraction_part
==
1000000
)
/* Carry across the decimal point */
{
fraction_part
=
0
;
integer_part
+=
1
;
}
UnityPrintNumberUnsigned
(
integer_part
);
UnityPrintDecimalAndNumberWithLeadingZeros
(
fraction_part
,
divisor
);
}
else
/* Number is larger, use exponential format of 9 digits, "%.8e" */
{
const
UNITY_INT32
divisor
=
1000000000
/
10
;
UNITY_INT32
integer_part
;
UNITY_DOUBLE_TYPE
divide
=
10
.
0
;
int
exponent
=
9
;
while
(
number
/
divide
>=
1000000000
.
0
-
0
.
5
)
{
divide
*=
10
;
exponent
++
;
}
integer_part
=
(
UNITY_INT32
)(
number
/
divide
+
0
.
5
);
/* Double precision calculation required for float, to produce 9 rounded digits */
ROUND_TIES_TO_EVEN
(
number
,
integer_part
,
number
/
divide
);
UNITY_OUTPUT_CHAR
(
'0'
+
integer_part
/
divisor
);
UnityPrintDecimalAndNumberWithLeadingZeros
(
integer_part
%
divisor
,
divisor
/
10
);
UNITY_OUTPUT_CHAR
(
'e'
);
UNITY_OUTPUT_CHAR
(
'+'
);
if
(
exponent
<
10
)
UNITY_OUTPUT_CHAR
(
'0'
);
UnityPrintNumber
(
exponent
);
}
}
#endif
#endif
/* ! UNITY_EXCLUDE_FLOAT_PRINT */
/*-----------------------------------------------*/
...
...
@@ -631,6 +701,19 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
#define UNITY_NAN_CHECK 0
#endif
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
#define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
do { \
UnityPrint(UnityStrExpected); \
UnityPrintFloat(expected); \
UnityPrint(UnityStrWas); \
UnityPrintFloat(actual); \
} while(0)
#else
#define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \
UnityPrint(UnityStrDelta)
#endif
/* UNITY_EXCLUDE_FLOAT_PRINT */
#ifndef UNITY_EXCLUDE_FLOAT
static
int
UnityFloatsWithin
(
UNITY_FLOAT
delta
,
UNITY_FLOAT
expected
,
UNITY_FLOAT
actual
)
{
...
...
@@ -665,14 +748,7 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected,
UnityTestResultsFailBegin
(
lineNumber
);
UnityPrint
(
UnityStrElement
);
UnityPrintNumberUnsigned
(
num_elements
-
elements
-
1
);
#ifdef UNITY_FLOAT_VERBOSE
UnityPrint
(
UnityStrExpected
);
UnityPrintFloat
(
*
ptr_expected
);
UnityPrint
(
UnityStrWas
);
UnityPrintFloat
(
*
ptr_actual
);
#else
UnityPrint
(
UnityStrDelta
);
#endif
UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT
(
*
ptr_expected
,
*
ptr_actual
);
UnityAddMsgIfSpecified
(
msg
);
UNITY_FAIL_AND_BAIL
;
}
...
...
@@ -694,14 +770,7 @@ void UnityAssertFloatsWithin(const UNITY_FLOAT delta,
if
(
!
UnityFloatsWithin
(
delta
,
expected
,
actual
))
{
UnityTestResultsFailBegin
(
lineNumber
);
#ifdef UNITY_FLOAT_VERBOSE
UnityPrint
(
UnityStrExpected
);
UnityPrintFloat
(
expected
);
UnityPrint
(
UnityStrWas
);
UnityPrintFloat
(
actual
);
#else
UnityPrint
(
UnityStrDelta
);
#endif
UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT
(
expected
,
actual
);
UnityAddMsgIfSpecified
(
msg
);
UNITY_FAIL_AND_BAIL
;
}
...
...
@@ -759,7 +828,7 @@ void UnityAssertFloatSpecial(const UNITY_FLOAT actual,
UnityPrint
(
UnityStrNot
);
UnityPrint
(
trait_names
[
trait_index
]);
UnityPrint
(
UnityStrWas
);
#if
def UNITY_FLOAT_VERBOSE
#if
ndef UNITY_EXCLUDE_FLOAT_PRINT
UnityPrintFloat
(
actual
);
#else
if
(
should_be_trait
)
...
...
@@ -808,14 +877,7 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expecte
UnityTestResultsFailBegin
(
lineNumber
);
UnityPrint
(
UnityStrElement
);
UnityPrintNumberUnsigned
(
num_elements
-
elements
-
1
);
#ifdef UNITY_DOUBLE_VERBOSE
UnityPrint
(
UnityStrExpected
);
UnityPrintFloat
((
float
)(
*
ptr_expected
));
UnityPrint
(
UnityStrWas
);
UnityPrintFloat
((
float
)(
*
ptr_actual
));
#else
UnityPrint
(
UnityStrDelta
);
#endif
UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT
(
*
ptr_expected
,
*
ptr_actual
);
UnityAddMsgIfSpecified
(
msg
);
UNITY_FAIL_AND_BAIL
;
}
...
...
@@ -836,14 +898,7 @@ void UnityAssertDoublesWithin(const UNITY_DOUBLE delta,
if
(
!
UnityDoublesWithin
(
delta
,
expected
,
actual
))
{
UnityTestResultsFailBegin
(
lineNumber
);
#ifdef UNITY_DOUBLE_VERBOSE
UnityPrint
(
UnityStrExpected
);
UnityPrintFloat
((
float
)
expected
);
UnityPrint
(
UnityStrWas
);
UnityPrintFloat
((
float
)
actual
);
#else
UnityPrint
(
UnityStrDelta
);
#endif
UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT
(
expected
,
actual
);
UnityAddMsgIfSpecified
(
msg
);
UNITY_FAIL_AND_BAIL
;
}
...
...
@@ -902,7 +957,7 @@ void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual,
UnityPrint
(
UnityStrNot
);
UnityPrint
(
trait_names
[
trait_index
]);
UnityPrint
(
UnityStrWas
);
#if
def UNITY_DOUBLE_VERBOSE
#if
ndef UNITY_EXCLUDE_FLOAT_PRINT
UnityPrintFloat
(
actual
);
#else
if
(
should_be_trait
)
...
...
src/unity.h
浏览文件 @
b0870ec8
...
...
@@ -37,13 +37,11 @@ void tearDown(void);
* - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons
* - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT
* - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats
* - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf)
* - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
* - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default)
* - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE
* - define UNITY_DOUBLE_TYPE to specify something other than double
* - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf)
* - define UNITY_VERBOSE_NUMBER_MAX_LENGTH to change maximum length of printed numbers (used by sprintf)
* - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors
* Output
* - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
...
...
src/unity_internals.h
浏览文件 @
b0870ec8
...
...
@@ -171,7 +171,6 @@
#undef UNITY_INCLUDE_FLOAT
#undef UNITY_FLOAT_PRECISION
#undef UNITY_FLOAT_TYPE
#undef UNITY_FLOAT_VERBOSE
#else
...
...
@@ -225,15 +224,19 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
/* 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_FLOAT_VERBOSE
typedef
UNITY_FLOAT
UNITY_DOUBLE
;
/* For parameter in UnityPrintFloat, double promotion required */
#ifdef UNITY_EXCLUDE_FLOAT
#define UNITY_EXCLUDE_FLOAT_PRINT
#else
#ifndef UNITY_DOUBLE_TYPE
#define UNITY_DOUBLE_TYPE double
#endif
typedef
UNITY_FLOAT
UNITY_DOUBLE
;
/* For parameter in UnityPrintFloat(UNITY_DOUBLE), which aliases to double or float */
#endif
#else
...
...
@@ -250,12 +253,6 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
#endif
#ifdef UNITY_DOUBLE_VERBOSE
#ifndef UNITY_FLOAT_VERBOSE
#define UNITY_FLOAT_VERBOSE
#endif
#endif
/*-------------------------------------------------------
* Output Method: stdout (DEFAULT)
*-------------------------------------------------------*/
...
...
@@ -443,7 +440,7 @@ void UnityPrintNumber(const UNITY_INT number);
void
UnityPrintNumberUnsigned
(
const
UNITY_UINT
number
);
void
UnityPrintNumberHex
(
const
UNITY_UINT
number
,
const
char
nibbles
);
#if
def UNITY_FLOAT_VERBOSE
#if
ndef UNITY_EXCLUDE_FLOAT_PRINT
void
UnityPrintFloat
(
const
UNITY_DOUBLE
number
);
#endif
...
...
test/tests/testunity.c
浏览文件 @
b0870ec8
...
...
@@ -5,8 +5,8 @@
========================================== */
#include "unity.h"
#include <setjmp.h>
#include <string.h>
#include <stdint.h>
// Dividing by these constants produces +/- infinity.
// The rationale is given in UnityAssertFloatIsInf's body.
...
...
@@ -59,19 +59,20 @@ static int SetToOneMeanWeAlreadyCheckedThisGuy;
void
setUp
(
void
)
{
SetToOneToFailInTearDown
=
0
;
SetToOneMeanWeAlreadyCheckedThisGuy
=
0
;
SetToOneToFailInTearDown
=
0
;
SetToOneMeanWeAlreadyCheckedThisGuy
=
0
;
}
void
tearDown
(
void
)
{
if
(
SetToOneToFailInTearDown
==
1
)
TEST_FAIL_MESSAGE
(
"<= Failed in tearDown"
);
if
((
SetToOneMeanWeAlreadyCheckedThisGuy
==
0
)
&&
(
Unity
.
CurrentTestFailed
>
0
))
{
UnityPrint
(
": [[[[ Test Should Have Passed But Did Not ]]]]"
);
UNITY_OUTPUT_CHAR
(
'\n'
);
}
endPutcharSpy
();
/* Stop suppressing test output */
if
(
SetToOneToFailInTearDown
==
1
)
TEST_FAIL_MESSAGE
(
"<= Failed in tearDown"
);
if
((
SetToOneMeanWeAlreadyCheckedThisGuy
==
0
)
&&
(
Unity
.
CurrentTestFailed
>
0
))
{
UnityPrint
(
": [[[[ Test Should Have Passed But Did Not ]]]]"
);
UNITY_OUTPUT_CHAR
(
'\n'
);
}
}
void
testUnitySizeInitializationReminder
(
void
)
...
...
@@ -2265,7 +2266,7 @@ void putcharSpy(int c)
if
(
indexSpyBuffer
<
SPY_BUFFER_MAX
-
1
)
putcharSpyBuffer
[
indexSpyBuffer
++
]
=
(
char
)
c
;
}
else
c
=
putchar
(
c
);
putchar
((
char
)
c
);
#endif
}
...
...
@@ -2284,10 +2285,14 @@ void testFailureCountIncrementsAndIsReturnedAtEnd(void)
void
testCstringsEscapeSequence
(
void
)
{
#ifndef USING_OUTPUT_SPY
TEST_IGNORE
();
#else
startPutcharSpy
();
UnityPrint
(
"
\x16\x10
"
);
endPutcharSpy
();
TEST_ASSERT_EQUAL_STRING
(
"
\\
x16
\\
x10"
,
getBufferPutcharSpy
());
#endif
}
#define TEST_ASSERT_EQUAL_PRINT_NUMBERS(expected, actual) { \
...
...
@@ -3227,6 +3232,180 @@ void testNotEqualFloatArraysLengthZero(void)
#endif
}
#define TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, actual) { \
startPutcharSpy(); UnityPrintFloat((actual)); endPutcharSpy(); \
TEST_ASSERT_EQUAL_STRING((expected), getBufferPutcharSpy()); \
}
void
testFloatPrinting
(
void
)
{
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.0"
,
0
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.000000..."
,
0
.
0000004
99
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.000001"
,
0
.
00000050000005
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.100469"
,
0
.
100469499
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.0"
,
0
.
9999995
f
);
/*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.0"
,
1
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.25"
,
1
.
25
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"7.999999"
,
7
.
999999
f
);
/*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000002"
,
16
.
000002
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000004"
,
16
.
000004
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000006"
,
16
.
000006
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4294967040.0"
,
4294967040
.
0
f
);
/*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.0"
,
-
0
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-0.000000..."
,
-
0
.
0000004
99
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-0.000001"
,
-
0
.
00000050000005
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-0.100469"
,
-
0
.
100469499
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1.0"
,
-
0
.
9999995
f
);
/*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1.0"
,
-
1
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1.25"
,
-
1
.
25
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-7.999999"
,
-
7
.
999999
f
);
/*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000002"
,
-
16
.
000002
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000004"
,
-
16
.
000004
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000006"
,
-
16
.
000006
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-4294967040.0"
,
-
4294967040
.
0
f
);
/*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.2949673e+09"
,
4294967296
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"5.0e+09"
,
5000000000
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"8.0e+09"
,
8.0e+09
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"8.3099991e+09"
,
8309999104
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.0e+10"
,
1.0e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.0e+10"
,
10000000000
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.00005499e+10"
,
1.000055e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.10000006e+38"
,
1.10000005e+38
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.63529943e+10"
,
1.63529943e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"3.40282347e+38"
,
3.40282346638e38
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1.0e+10"
,
-
1.0e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-3.40282347e+38"
,
-
3.40282346638e38
f
);
#endif
}
void
testFloatPrintingRoundTiesToEven
(
void
)
{
#if defined(UNITY_EXCLUDE_FLOAT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
#ifdef UNITY_ROUND_TIES_AWAY_FROM_ZERO
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.007813"
,
0
.
007
8125
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.976563"
,
0
.
9765625
f
);
#else
/* Default to Round ties to even */
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.007182"
,
0
.
0071
825
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.976562"
,
0
.
9765625
f
);
#endif
#endif
}
void
testFloatPrintingInfinityAndNaN
(
void
)
{
#if defined(UNITY_EXCLUDE_FLOAT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"Inf"
,
1
.
0
f
/
f_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-Inf"
,
-
1
.
0
f
/
f_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"NaN"
,
0
.
0
f
/
f_zero
);
#endif
}
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
static
void
AllFloatPrinting_LessThan32Bits
(
void
)
{
char
expected
[
18
];
union
{
float
f_value
;
int32_t
int_value
;
}
u
;
/* Float representations are laid out in integer order, walk up the list */
for
(
u
.
f_value
=
0
.
00000050000005
f
;
u
.
f_value
<=
4294967040
.
0
f
;
u
.
int_value
+=
1
)
{
startPutcharSpy
();
UnityPrintFloat
(
u
.
f_value
);
/*1.5x as fast as sprintf 5e-7f - 0.01f, 20s vs 30s*/
int
len
=
sprintf
(
expected
,
"%.6f"
,
u
.
f_value
);
while
(
expected
[
len
-
1
]
==
'0'
&&
expected
[
len
-
2
]
!=
'.'
)
{
len
--
;
}
expected
[
len
]
=
'\0'
;
/* delete trailing 0's */
if
(
strcmp
(
expected
,
getBufferPutcharSpy
())
!=
0
)
{
double
six_digits
=
((
double
)
u
.
f_value
-
(
uint32_t
)
u
.
f_value
)
*
1000000
.
0
;
/* Not a tie (remainder != 0.5) => Can't explain the different strings */
if
(
six_digits
-
(
uint32_t
)
six_digits
!=
0
.
5
)
{
/* Fail with diagnostic printing */
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
expected
,
u
.
f_value
);
}
}
}
}
/* Compared to perfect, floats are occasionally rounded wrong. It doesn't affect
* correctness, though. Two examples (of 13 total found during testing):
* Printed: 6.19256349e+20, Exact: 619256348499999981568.0f <= Eliminated by ROUND_TIES_TO_EVEN
* Printed: 2.19012272e+35, Exact: 219012271499999993621766990196637696.0f */
static
void
AllFloatPrinting_Larger
(
const
float
start
,
const
float
end
)
{
unsigned
int
wrong
=
0
;
char
expected
[
18
];
union
{
float
f_value
;
int32_t
int_value
;
}
u
;
for
(
u
.
f_value
=
start
;
u
.
f_value
<=
end
;
u
.
int_value
+=
1
)
{
startPutcharSpy
();
UnityPrintFloat
(
u
.
f_value
);
/*Twice as fast as sprintf 2**32-1e12, 10s vs 21s*/
sprintf
(
expected
,
"%.8e"
,
u
.
f_value
);
int
len
=
11
-
1
;
/* 11th char is 'e' in exponential format */
while
(
expected
[
len
-
1
]
==
'0'
&&
expected
[
len
-
2
]
!=
'.'
)
{
len
--
;
}
if
(
expected
[
14
]
!=
'\0'
)
memmove
(
&
expected
[
12
],
&
expected
[
13
],
3
);
/* Two char exponent */
memmove
(
&
expected
[
len
],
&
expected
[
11
-
1
],
sizeof
"e+09"
);
/* 5 char length */
if
(
strcmp
(
expected
,
getBufferPutcharSpy
())
!=
0
)
{
wrong
++
;
/* endPutcharSpy(); UnityPrint("Expected "); UnityPrint(expected);
UnityPrint(" Was "); UnityPrint(getBufferPutcharSpy()); UNITY_OUTPUT_CHAR('\n'); */
if
(
wrong
>
10
||
(
wrong
>
3
&&
end
<=
1e25
f
))
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
expected
,
u
.
f_value
);
/* Empirical values from the current routine, don't be worse when making changes */
}
}
}
#endif
/* Exhaustive testing of all float values we differentiate when printing. Doubles
* are not explored here -- too many. These tests confirm that the routine works
* for all floats > 5e-7, positives only. Off by default due to test time.
* Compares Unity's routine to your sprintf() C lib, tested to pass on 3 platforms.
* Part1 takes a long time, around 3 minutes compiled with -O2
* Runs through all floats from 0.000001 - 2**32, ~300 million values */
void
testAllFloatPrintingPart1_LessThan32Bits
(
void
)
{
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
AllFloatPrinting_LessThan32Bits
();
#else
TEST_IGNORE
();
/* Ignore one of three */
#endif
}
/* Test takes a long time, around 3.5 minutes compiled with -O2, try ~500 million values */
void
testAllFloatPrintingPart2_Larger
(
void
)
{
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
AllFloatPrinting_Larger
(
4294967296
.
0
f
,
1e25
f
);
#endif
}
/* Test takes a long time, around 3.5 minutes compiled with -O2, try ~500 million values */
void
testAllFloatPrintingPart3_LargerStill
(
void
)
{
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
AllFloatPrinting_Larger
(
1e25
f
,
3.40282347e+38
f
);
#endif
}
// ===================== THESE TEST WILL RUN IF YOUR CONFIG INCLUDES DOUBLE SUPPORT ==================
void
testDoublesWithinDelta
(
void
)
...
...
@@ -3750,6 +3929,55 @@ void testNotEqualDoubleArraysLengthZero(void)
#endif
}
void
testDoublePrinting
(
void
)
{
#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.100469"
,
0
.
10046949999999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4294967295.999999"
,
4294967295
.
999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.2949673e+09"
,
4294967295
.
9999995
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.2949673e+09"
,
4294967296
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.0e+10"
,
9999999995
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"9.00719925e+15"
,
9007199254740990
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"7.0e+100"
,
7.0e+100
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"3.0e+200"
,
3.0e+200
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"9.23456789e+300"
,
9.23456789e+300
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-0.100469"
,
-
0
.
10046949999999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-4294967295.999999"
,
-
4294967295
.
999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-4.2949673e+09"
,
-
4294967295
.
9999995
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-7.0e+100"
,
-
7.0e+100
);
#endif
}
void
testDoublePrintingRoundTiesToEven
(
void
)
{
#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
#ifdef UNITY_ROUND_TIES_AWAY_FROM_ZERO
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.00000001e+10"
,
10000000050
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"9.00719925e+15"
,
9007199245000000
.
0
);
#else
/* Default to Round ties to even */
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.0e+10"
,
10000000050
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"9.00719924e+15"
,
9007199245000000
.
0
);
#endif
#endif
}
void
testDoublePrintingInfinityAndNaN
(
void
)
{
#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"Inf"
,
1
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-Inf"
,
-
1
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"NaN"
,
0
.
0
/
d_zero
);
#endif
}
// ===================== THESE TEST WILL RUN IF YOUR CONFIG INCLUDES DETAIL SUPPORT ==================
void
testThatDetailsCanBeHandleOneDetail
(
void
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录