Commit 7e24024f authored by Milo Yip's avatar Milo Yip

Merge pull request #293 from miloyip/issue287_WarningFloatEqual

Add -Wfloat-equal and fix all derived warnings 
parents a0a361d2 5ae85e67
...@@ -700,8 +700,10 @@ public: ...@@ -700,8 +700,10 @@ public:
return StringEqual(rhs); return StringEqual(rhs);
case kNumberType: case kNumberType:
if (IsDouble() || rhs.IsDouble()) if (IsDouble() || rhs.IsDouble()) {
return GetDouble() == rhs.GetDouble(); // May convert one operand from integer to double. float delta = GetDouble() - rhs.GetDouble(); // May convert one operand from integer to double.
return delta >= 0.0 && delta <= 0.0; // Prevent -Wfloat-equal
}
else else
return data_.n.u64 == rhs.data_.n.u64; return data_.n.u64 == rhs.data_.n.u64;
......
...@@ -238,7 +238,7 @@ inline DiyFp GetCachedPower(int e, int* K) { ...@@ -238,7 +238,7 @@ inline DiyFp GetCachedPower(int e, int* K) {
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374; //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
int k = static_cast<int>(dk); int k = static_cast<int>(dk);
if (k != dk) if (dk - k > 0.0)
k++; k++;
unsigned index = static_cast<unsigned>((k >> 3) + 1); unsigned index = static_cast<unsigned>((k >> 3) + 1);
......
...@@ -193,8 +193,8 @@ inline char* Prettify(char* buffer, int length, int k) { ...@@ -193,8 +193,8 @@ inline char* Prettify(char* buffer, int length, int k) {
} }
inline char* dtoa(double value, char* buffer) { inline char* dtoa(double value, char* buffer) {
if (value == 0) { Double d(value);
Double d(value); if (d.IsZero()) {
if (d.Sign()) if (d.Sign())
*buffer++ = '-'; // -0.0, Issue #289 *buffer++ = '-'; // -0.0, Issue #289
buffer[0] = '0'; buffer[0] = '0';
......
...@@ -36,7 +36,7 @@ public: ...@@ -36,7 +36,7 @@ public:
double PreviousPositiveDouble() const { double PreviousPositiveDouble() const {
RAPIDJSON_ASSERT(!Sign()); RAPIDJSON_ASSERT(!Sign());
if (d == 0.0) if (IsZero())
return 0.0; return 0.0;
else else
return Double(u - 1).Value(); return Double(u - 1).Value();
...@@ -49,6 +49,7 @@ public: ...@@ -49,6 +49,7 @@ public:
bool IsNan() const { return (u & kExponentMask) == kExponentMask && Significand() != 0; } bool IsNan() const { return (u & kExponentMask) == kExponentMask && Significand() != 0; }
bool IsInf() const { return (u & kExponentMask) == kExponentMask && Significand() == 0; } bool IsInf() const { return (u & kExponentMask) == kExponentMask && Significand() == 0; }
bool IsNormal() const { return (u & kExponentMask) != 0 || Significand() == 0; } bool IsNormal() const { return (u & kExponentMask) != 0 || Significand() == 0; }
bool IsZero() const { return (u & (kExponentMask | kSignificandMask)) == 0; }
uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
......
...@@ -896,7 +896,7 @@ private: ...@@ -896,7 +896,7 @@ private:
if (significandDigit < 17) { if (significandDigit < 17) {
d = d * 10.0 + (s.TakePush() - '0'); d = d * 10.0 + (s.TakePush() - '0');
--expFrac; --expFrac;
if (d != 0.0) if (d > 0.0)
significandDigit++; significandDigit++;
} }
else else
......
...@@ -14,9 +14,9 @@ set(UNITTEST_SOURCES ...@@ -14,9 +14,9 @@ set(UNITTEST_SOURCES
writertest.cpp) writertest.cpp)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Weffc++ -Wswitch-default") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Weffc++ -Wswitch-default") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
endif() endif()
......
...@@ -63,7 +63,7 @@ void ParseTest() { ...@@ -63,7 +63,7 @@ void ParseTest() {
EXPECT_TRUE(doc.HasMember("pi")); EXPECT_TRUE(doc.HasMember("pi"));
const ValueType& pi = doc["pi"]; const ValueType& pi = doc["pi"];
EXPECT_TRUE(pi.IsNumber()); EXPECT_TRUE(pi.IsNumber());
EXPECT_EQ(3.1416, pi.GetDouble()); EXPECT_DOUBLE_EQ(3.1416, pi.GetDouble());
EXPECT_TRUE(doc.HasMember("a")); EXPECT_TRUE(doc.HasMember("a"));
const ValueType& a = doc["a"]; const ValueType& a = doc["a"];
......
...@@ -30,6 +30,7 @@ using namespace rapidjson; ...@@ -30,6 +30,7 @@ using namespace rapidjson;
#ifdef __GNUC__ #ifdef __GNUC__
RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++) RAPIDJSON_DIAG_OFF(effc++)
RAPIDJSON_DIAG_OFF(float-equal)
#endif #endif
template<bool expect> template<bool expect>
...@@ -190,7 +191,7 @@ static void TestParseDouble() { ...@@ -190,7 +191,7 @@ static void TestParseDouble() {
internal::Double e(x), a(h.actual_); \ internal::Double e(x), a(h.actual_); \
EXPECT_EQ(e.Sign(), a.Sign()); \ EXPECT_EQ(e.Sign(), a.Sign()); \
if (fullPrecision) { \ if (fullPrecision) { \
EXPECT_EQ(x, h.actual_); \ EXPECT_NEAR(x, h.actual_, 0.0); \
if (x != h.actual_) \ if (x != h.actual_) \
printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", str, h.actual_, x); \ printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", str, h.actual_, x); \
} \ } \
...@@ -662,7 +663,7 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> { ...@@ -662,7 +663,7 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
} }
} }
bool Uint(unsigned i) { return Int(i); } bool Uint(unsigned i) { return Int(i); }
bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_EQ(3.1416, d); step_++; return true; } bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
bool String(const char* str, size_t, bool) { bool String(const char* str, size_t, bool) {
switch(step_) { switch(step_) {
case 1: EXPECT_STREQ("hello", str); step_++; return true; case 1: EXPECT_STREQ("hello", str); step_++; return true;
......
...@@ -339,7 +339,7 @@ TEST(Value, Int) { ...@@ -339,7 +339,7 @@ TEST(Value, Int) {
EXPECT_EQ(1234u, x.GetUint()); EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64()); EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64()); EXPECT_EQ(1234u, x.GetUint64());
EXPECT_EQ(1234, x.GetDouble()); EXPECT_NEAR(1234.0, x.GetDouble(), 0.0);
//EXPECT_EQ(1234, (int)x); //EXPECT_EQ(1234, (int)x);
//EXPECT_EQ(1234, (unsigned)x); //EXPECT_EQ(1234, (unsigned)x);
//EXPECT_EQ(1234, (int64_t)x); //EXPECT_EQ(1234, (int64_t)x);
...@@ -397,7 +397,7 @@ TEST(Value, Uint) { ...@@ -397,7 +397,7 @@ TEST(Value, Uint) {
EXPECT_TRUE(x.IsUint()); EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64()); EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64()); EXPECT_TRUE(x.IsUint64());
EXPECT_EQ(1234.0, x.GetDouble()); // Number can always be cast as double but !IsDouble(). EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble().
EXPECT_FALSE(x.IsDouble()); EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsNull()); EXPECT_FALSE(x.IsNull());
...@@ -517,7 +517,7 @@ TEST(Value, Double) { ...@@ -517,7 +517,7 @@ TEST(Value, Double) {
// Constructor with double // Constructor with double
Value x(12.34); Value x(12.34);
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(12.34, x.GetDouble()); EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
EXPECT_TRUE(x.IsNumber()); EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsDouble()); EXPECT_TRUE(x.IsDouble());
...@@ -533,10 +533,10 @@ TEST(Value, Double) { ...@@ -533,10 +533,10 @@ TEST(Value, Double) {
// SetDouble() // SetDouble()
Value z; Value z;
z.SetDouble(12.34); z.SetDouble(12.34);
EXPECT_EQ(12.34, z.GetDouble()); EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
z = 56.78; z = 56.78;
EXPECT_EQ(56.78, z.GetDouble()); EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
} }
TEST(Value, String) { TEST(Value, String) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment