Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
soft
thingsee-sdk
Commits
62321f8a
Commit
62321f8a
authored
Oct 08, 2015
by
Jussi Kivilinna
Committed by
Pekka Niemimaa
Oct 12, 2015
Browse files
netutils/cJSON: make print numbers more accurate
Signed-off-by:
Jussi Kivilinna
<
jussi.kivilinna@haltian.com
>
parent
38826d39
Changes
1
Hide whitespace changes
Inline
Side-by-side
apps/netutils/json/cJSON_stream_print.c
View file @
62321f8a
...
...
@@ -104,6 +104,13 @@ static inline void stream_puts(cJSON_outstream *stream, char *string)
}
}
static
bool
dbl_equal
(
double
a
,
double
b
)
{
double
fabs_a
=
fabs
(
a
);
double
fabs_b
=
fabs
(
b
);
return
fabs
(
a
-
b
)
<=
((
fabs_a
>
fabs_b
?
fabs_b
:
fabs_a
)
*
DBL_EPSILON
);
}
/* Render the number nicely from the given item into a string. */
static
void
stream_print_number
(
cJSON
*
item
,
cJSON_outstream
*
stream
)
...
...
@@ -116,20 +123,58 @@ static void stream_print_number(cJSON *item, cJSON_outstream *stream)
/* Get type and needed length output string. */
if
((
d
<=
INT_MAX
&&
d
>=
INT_MIN
)
&&
(
fabs
(
id
-
d
)
<=
DBL_EPSILON
||
fabs
(
floor
(
d
)
-
d
)
<=
DBL_EPSILON
))
if
(
item
->
valueint
==
0
&&
d
==
0
.
0
)
{
/* Handle zero separately as it's relation to DBL_EPSILON is special one
* and as zero has two exact presentations in floating point format (positive
* zero and negative zero). */
if
(
copysign
(
1
.
0
,
d
)
>
0
.
0
)
{
/* Simply zero. */
str
[
0
]
=
'0'
;
str
[
1
]
=
'\0'
;
slen
=
1
;
type
=
3
;
}
else
{
/* Negative zero. */
slen
=
snprintf
(
str
,
sizeof
(
str
),
"%s"
,
"-0.0"
);
type
=
2
;
}
}
else
if
(
item
->
valueint
!=
0
&&
(
d
<=
INT_MAX
&&
d
>=
INT_MIN
)
&&
dbl_equal
(
d
,
id
))
{
/* Integer value can accurately represent this value. */
slen
=
snprintf
(
str
,
sizeof
(
str
),
"%d"
,
item
->
valueint
);
type
=
1
;
}
else
if
(
fabs
(
d
)
<
1.0e-6
||
fabs
(
d
)
>
1.0e
9
)
else
if
(
fabs
(
d
)
<
1.0e-6
||
fabs
(
d
)
>
1.0e
14
)
{
slen
=
snprintf
(
str
,
sizeof
(
str
),
"%e"
,
d
);
/* Double can represent 15 significant digits. */
slen
=
snprintf
(
str
,
sizeof
(
str
),
"%.14e"
,
d
);
type
=
-
1
;
}
else
{
slen
=
snprintf
(
str
,
sizeof
(
str
),
"%.10f"
,
d
);
int
ndigits_before_dot
=
(
int
)
log10
(
fabs
(
d
));
int
ndigits_after_dot
=
15
-
ndigits_before_dot
;
char
fmtstr
[
8
];
/* Double can represent 15 significant digits. */
if
(
ndigits_after_dot
<
0
)
ndigits_after_dot
=
0
;
snprintf
(
fmtstr
,
sizeof
(
fmtstr
),
"%%.%df"
,
ndigits_after_dot
);
slen
=
snprintf
(
str
,
sizeof
(
str
),
fmtstr
,
d
);
type
=
0
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment