Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Unity
提交
0547aab6
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看板
提交
0547aab6
编写于
8月 25, 2017
作者:
M
Mark VanderVoord
提交者:
GitHub
8月 25, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #291 from jlindgren90/master
Rewrite UnityPrintFloat to match printf("%.6g").
上级
a868b2eb
2ae2bdb3
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
173 addition
and
237 deletion
+173
-237
src/unity.c
src/unity.c
+76
-74
test/tests/testunity.c
test/tests/testunity.c
+97
-163
未找到文件。
src/unity.c
浏览文件 @
0547aab6
...
...
@@ -235,95 +235,97 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
/*-----------------------------------------------*/
#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);
*/
/* This function prints a floating-point value in a format similar to
* printf("%.6g"). It can work with either single- or double-precision,
* but for simplicity, it prints only 6 significant digits in either case.
* Printing more than 6 digits accurately is hard (at least in the single-
* precision case) and isn't attempted here. */
void
UnityPrintFloat
(
const
UNITY_DOUBLE
input_number
)
{
UNITY_DOUBLE
number
;
UNITY_DOUBLE
number
=
input_number
;
if
(
input_number
<
0
)
/* print minus sign (including for negative zero) */
if
(
number
<
0
.
0
f
||
(
number
==
0
.
0
f
&&
1
.
0
f
/
number
<
0
.
0
f
))
{
UNITY_OUTPUT_CHAR
(
'-'
);
number
=
-
input_number
;
}
else
{
number
=
input_number
;
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 */
/* handle zero, NaN, and +/- infinity */
if
(
number
==
0
.
0
f
)
UnityPrint
(
"0"
);
else
if
(
isnan
(
number
))
UnityPrint
(
"nan"
);
else
if
(
isinf
(
number
))
UnityPrint
(
"inf"
);
else
{
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
);
int
exponent
=
0
;
int
decimals
,
digits
;
UNITY_INT32
n
;
char
buf
[
16
];
/* scale up or down by powers of 10 */
while
(
number
<
100000
.
0
f
/
1e6
f
)
{
number
*=
1e6
f
;
exponent
-=
6
;
}
while
(
number
<
100000
.
0
f
)
{
number
*=
10
.
0
f
;
exponent
--
;
}
while
(
number
>
1000000
.
0
f
*
1e6
f
)
{
number
/=
1e6
f
;
exponent
+=
6
;
}
while
(
number
>
1000000
.
0
f
)
{
number
/=
10
.
0
f
;
exponent
++
;
}
if
(
fraction_part
==
1000000
)
/* Carry across the decimal point */
/* round to nearest integer */
n
=
((
UNITY_INT32
)(
number
+
number
)
+
1
)
/
2
;
if
(
n
>
999999
)
{
fraction_part
=
0
;
integer_part
+=
1
;
n
=
10000
0
;
exponent
++
;
}
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
;
/* determine where to place decimal point */
decimals
=
(
exponent
<=
0
&&
exponent
>=
-
9
)
?
-
exponent
:
5
;
exponent
+=
decimals
;
while
(
number
/
divide
>=
1000000000
.
0
-
0
.
5
)
/* truncate trailing zeroes after decimal point */
while
(
decimals
>
0
&&
n
%
10
==
0
)
{
divide
*=
10
;
exponent
++
;
n
/=
10
;
decimals
--
;
}
/* build up buffer in reverse order */
digits
=
0
;
while
(
n
!=
0
||
digits
<
decimals
+
1
)
{
buf
[
digits
++
]
=
(
char
)(
'0'
+
n
%
10
);
n
/=
10
;
}
while
(
digits
>
0
)
{
if
(
digits
==
decimals
)
UNITY_OUTPUT_CHAR
(
'.'
);
UNITY_OUTPUT_CHAR
(
buf
[
--
digits
]);
}
/* print exponent if needed */
if
(
exponent
!=
0
)
{
UNITY_OUTPUT_CHAR
(
'e'
);
if
(
exponent
<
0
)
{
UNITY_OUTPUT_CHAR
(
'-'
);
exponent
=
-
exponent
;
}
else
{
UNITY_OUTPUT_CHAR
(
'+'
);
}
digits
=
0
;
while
(
exponent
!=
0
||
digits
<
2
)
{
buf
[
digits
++
]
=
(
char
)(
'0'
+
exponent
%
10
);
exponent
/=
10
;
}
while
(
digits
>
0
)
{
UNITY_OUTPUT_CHAR
(
buf
[
--
digits
]);
}
}
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
/* ! UNITY_EXCLUDE_FLOAT_PRINT */
...
...
test/tests/testunity.c
浏览文件 @
0547aab6
...
...
@@ -4056,61 +4056,46 @@ 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.99999
9"
,
7
.
9
99999
f
);
/*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000
002"
,
16
.
00
0002
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000
004"
,
16
.
00
0004
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000
006"
,
16
.
00
0006
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.99999
9"
,
-
7
.
9
99999
f
);
/*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000
002"
,
-
16
.
00
0002
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000
004"
,
-
16
.
00
0004
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000
006"
,
-
16
.
00
0006
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
4294967040.0"
,
-
4294967040
.
0
f
);
/*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.2949
673e+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.3
099991e+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
(
"0
"
,
0
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
4.99e-07
"
,
0
.
0000004
99
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
5e-07
"
,
0
.
00000050000005
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.100469"
,
0
.
100469499
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1
"
,
0
.
9999995
f
);
/*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1
"
,
1
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.25"
,
1
.
25
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"7.99999
"
,
7
.
99999
f
);
/*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000
2"
,
16
.
0002
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000
4"
,
16
.
0004
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"16.000
6"
,
16
.
0006
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
999999"
,
999999
.
0
f
);
/*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
-
0"
,
-
0
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
4.99e-07"
,
-
0
.
0000004
99
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
5e-07"
,
-
0
.
00000050000005
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-0.100469"
,
-
0
.
100469499
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1
"
,
-
0
.
9999995
f
);
/*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1
"
,
-
1
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1.25"
,
-
1
.
25
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-7.99999
"
,
-
7
.
99999
f
);
/*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000
2"
,
-
16
.
0002
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000
4"
,
-
16
.
0004
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-16.000
6"
,
-
16
.
0006
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
999999"
,
-
999999
.
0
f
);
/*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.2949
7e+09"
,
4294967296
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"5
e+09"
,
5000000000
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"8
e+09"
,
8.0e+09
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"8.3
1e+09"
,
8309999104
.
0
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1
e+10"
,
1.0e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1
e+10"
,
10000000000
.
0
f
);
/* Some compilers have trouble with inexact float constants, a float cast works generally */
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.00005
499e+10"
,
(
float
)
1.000055
e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.1
0000006e+38"
,
(
float
)
1.10000005e+38
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.635
29943e+10"
,
1.63529943e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"3.40282
347
e+38"
,
3.40282346638e38
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.00005
e+10"
,
(
float
)
1.000054
e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.1
e+38"
,
(
float
)
1.10000005e+38
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1.635
3e+10"
,
1.63529943e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"3.40282e+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_PRINT) || !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
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-1e+10"
,
-
1.0e+10
f
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-3.40282e+38"
,
-
3.40282346638e38
f
);
#endif
}
...
...
@@ -4119,105 +4104,69 @@ void testFloatPrintingInfinityAndNaN(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
I
nf"
,
1
.
0
f
/
f_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
I
nf"
,
-
1
.
0
f
/
f_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
i
nf"
,
1
.
0
f
/
f_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
i
nf"
,
-
1
.
0
f
/
f_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
NaN
"
,
0
.
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
)
static
void
printFloatValue
(
float
f
)
{
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
);
}
}
}
}
char
expected_lower
[
18
];
char
expected_higher
[
18
];
/* 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
();
startPutcharSpy
();
UnityPrintFloat
(
u
.
f_value
);
/*Twice as fast as sprintf 2**32-1e12, 10s vs 21s*/
sprintf
(
expected
,
"%.8e"
,
u
.
f_value
);
UnityPrintFloat
(
f
);
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 */
sprintf
(
expected
,
"%.6g"
,
f
);
if
(
strcmp
(
expected
,
getBufferPutcharSpy
())
!=
0
)
{
wrong
++
;
/* endPutcharSpy(); UnityPrint("Expected "); UnityPrint(expected);
UnityPrint(" Was "); UnityPrint(getBufferPutcharSpy()); UNITY_OUTPUT_CHAR('\n'); */
/* We print all NaN's as "nan", not "-nan" */
if
(
strcmp
(
expected
,
"-nan"
)
==
0
)
strcpy
(
expected
,
"nan"
);
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 */
}
/* Allow for rounding differences in last digit */
double
lower
=
(
double
)
f
*
0
.
9999995
;
double
higher
=
(
double
)
f
*
1
.
0000005
;
if
(
isfinite
(
lower
))
sprintf
(
expected_lower
,
"%.6g"
,
lower
);
else
strcpy
(
expected_lower
,
expected
);
if
(
isfinite
(
higher
))
sprintf
(
expected_higher
,
"%.6g"
,
higher
);
else
strcpy
(
expected_higher
,
expected
);
if
(
strcmp
(
expected
,
getBufferPutcharSpy
())
!=
0
&&
strcmp
(
expected_lower
,
getBufferPutcharSpy
())
!=
0
&&
strcmp
(
expected_higher
,
getBufferPutcharSpy
())
!=
0
)
{
/* Fail with diagnostic printing */
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
expected
,
f
);
}
}
#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
)
void
testFloatPrintingRandomSamples
(
void
)
{
#if
defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) &&
defined(USING_OUTPUT_SPY)
AllFloatPrinting_LessThan32Bits
();
#if
!defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) || !
defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_IGNORE
();
/* Ignore one of three */
#endif
}
union
{
float
f_value
;
uint32_t
int_value
;
}
u
;
/* 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
}
/* These values are not covered by the MINSTD generator */
u
.
int_value
=
0x00000000
;
printFloatValue
(
u
.
f_value
);
u
.
int_value
=
0x80000000
;
printFloatValue
(
u
.
f_value
);
u
.
int_value
=
0x7fffffff
;
printFloatValue
(
u
.
f_value
);
u
.
int_value
=
0xffffffff
;
printFloatValue
(
u
.
f_value
);
/* 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
);
uint32_t
a
=
1
;
for
(
int
num_tested
=
0
;
num_tested
<
1000000
;
num_tested
++
)
{
/* MINSTD pseudo-random number generator */
a
=
(
uint32_t
)(((
uint64_t
)
a
*
48271u
)
%
2147483647u
);
/* MINSTD does not set the highest bit; test both possibilities */
u
.
int_value
=
a
;
printFloatValue
(
u
.
f_value
);
u
.
int_value
=
a
|
0x80000000
;
printFloatValue
(
u
.
f_value
);
}
#endif
}
...
...
@@ -4893,35 +4842,20 @@ void testDoublePrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || 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
}
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"0.100469"
,
0
.
10046949999999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.29497e+09"
,
4294967295
.
999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.29497e+09"
,
4294967295
.
9999995
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"4.29497e+09"
,
4294967296
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"1e+10"
,
9999999995
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"9.0072e+15"
,
9007199254740990
.
0
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"7e+100"
,
7.0e+100
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"3e+200"
,
3.0e+200
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"9.23457e+300"
,
9.23456789e+300
);
void
testDoublePrintingRoundTiesToEven
(
void
)
{
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || 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
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-0.100469"
,
-
0
.
10046949999999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-4.29497e+09"
,
-
4294967295
.
999999
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-4.29497e+09"
,
-
4294967295
.
9999995
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-7e+100"
,
-
7.0e+100
);
#endif
}
...
...
@@ -4930,10 +4864,10 @@ void testDoublePrintingInfinityAndNaN(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE
();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
I
nf"
,
1
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
I
nf"
,
-
1
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
i
nf"
,
1
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"-
i
nf"
,
-
1
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
NaN
"
,
0
.
0
/
d_zero
);
TEST_ASSERT_EQUAL_PRINT_FLOATING
(
"
nan
"
,
0
.
0
/
d_zero
);
#endif
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录