Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix clang -Wfloat-equal warning #368

Merged
merged 2 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ if (ENABLE_CUSTOM_COMPILER_FLAGS)
-Wmissing-variable-declarations
-Wused-but-marked-unused
-Wswitch-enum
-Wfloat-equal
)
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# Disable warning c4001 - nonstandard extension 'single line comment' was used
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ else
endif

PIC_FLAGS = -fPIC
R_CFLAGS = $(PIC_FLAGS) -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion $(CFLAGS)
R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion -Wfloat-equal $(CFLAGS)

uname := $(shell sh -c 'uname -s 2>/dev/null || echo false')

Expand Down
12 changes: 9 additions & 3 deletions cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,12 @@ static void update_offset(printbuffer * const buffer)
buffer->offset += strlen((const char*)buffer_pointer);
}

/* securely comparison of floating-point variables */
static cJSON_bool compare_double(double a, double b)
{
return (fabs(a - b) <= a * CJSON_DOUBLE_PRECIION);
}

/* Render the number nicely from the given item into a string. */
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
{
Expand All @@ -497,7 +503,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
}

/* This checks for NaN and Infinity */
if ((d * 0) != 0)
if (!compare_double(d * 0, 0))
{
length = sprintf((char*)number_buffer, "null");
}
Expand All @@ -507,7 +513,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
length = sprintf((char*)number_buffer, "%1.15g", d);

/* Check whether the original double can be recovered */
if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
{
/* If not, print with 17 decimal places of precision */
length = sprintf((char*)number_buffer, "%1.17g", d);
Expand Down Expand Up @@ -2876,7 +2882,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
return true;

case cJSON_Number:
if (a->valuedouble == b->valuedouble)
if (compare_double(a->valuedouble, b->valuedouble))
{
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions cJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ typedef int cJSON_bool;
#define CJSON_NESTING_LIMIT 1000
#endif

/* Precision of double variables comparison */
#ifndef CJSON_DOUBLE_PRECIION
#define CJSON_DOUBLE_PRECIION .00001
#endif

/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);

Expand Down
12 changes: 10 additions & 2 deletions cJSON_Utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>

#if defined(_MSC_VER)
#pragma warning (pop)
Expand Down Expand Up @@ -105,6 +106,13 @@ static int compare_strings(const unsigned char *string1, const unsigned char *st
return tolower(*string1) - tolower(*string2);
}

/* securely comparison of floating-point variables */
static cJSON_bool compare_double(double a, double b)
{
return (fabs(a - b) <= a * CJSON_DOUBLE_PRECIION);
}


/* Compare the next path element of two JSON pointers, two NULL pointers are considered unequal: */
static cJSON_bool compare_pointers(const unsigned char *name, const unsigned char *pointer, const cJSON_bool case_sensitive)
{
Expand Down Expand Up @@ -596,7 +604,7 @@ static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensiti
{
case cJSON_Number:
/* numeric mismatch. */
if ((a->valueint != b->valueint) || (a->valuedouble != b->valuedouble))
if ((a->valueint != b->valueint) || (!compare_double(a->valuedouble, b->valuedouble)))
{
return false;
}
Expand Down Expand Up @@ -1136,7 +1144,7 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa
switch (from->type & 0xFF)
{
case cJSON_Number:
if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
if ((from->valueint != to->valueint) || (compare_double(from->valuedouble, to->valuedouble)))
{
compose_patch(patches, (const unsigned char*)"replace", path, NULL, to);
}
Expand Down