mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Fixed too many decimals places in float serialization (issue #543)
This commit is contained in:
		| @@ -14,7 +14,8 @@ | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| void check(double input, const std::string& expected) { | ||||
| template <typename TFloat> | ||||
| void check(TFloat input, const std::string& expected) { | ||||
|   std::string output; | ||||
|   DynamicStringBuilder<std::string> sb(output); | ||||
|   JsonWriter<DynamicStringBuilder<std::string> > writer(sb); | ||||
| @@ -23,83 +24,93 @@ void check(double input, const std::string& expected) { | ||||
|   CHECK(expected == output); | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonWriter::writeFloat()") { | ||||
| TEST_CASE("JsonWriter::writeFloat(double)") { | ||||
|   SECTION("Pi") { | ||||
|     check(3.14159265359, "3.141592654"); | ||||
|     check<double>(3.14159265359, "3.141592654"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Signaling NaN") { | ||||
|     double nan = std::numeric_limits<double>::signaling_NaN(); | ||||
|     check(nan, "NaN"); | ||||
|     check<double>(nan, "NaN"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Quiet NaN") { | ||||
|     double nan = std::numeric_limits<double>::quiet_NaN(); | ||||
|     check(nan, "NaN"); | ||||
|     check<double>(nan, "NaN"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Infinity") { | ||||
|     double inf = std::numeric_limits<double>::infinity(); | ||||
|     check(inf, "Infinity"); | ||||
|     check(-inf, "-Infinity"); | ||||
|     check<double>(inf, "Infinity"); | ||||
|     check<double>(-inf, "-Infinity"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Zero") { | ||||
|     check(0.0, "0"); | ||||
|     check(-0.0, "0"); | ||||
|     check<double>(0.0, "0"); | ||||
|     check<double>(-0.0, "0"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Espilon") { | ||||
|     check(2.2250738585072014E-308, "2.225073859e-308"); | ||||
|     check(-2.2250738585072014E-308, "-2.225073859e-308"); | ||||
|     check<double>(2.2250738585072014E-308, "2.225073859e-308"); | ||||
|     check<double>(-2.2250738585072014E-308, "-2.225073859e-308"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Max double") { | ||||
|     check(1.7976931348623157E+308, "1.797693135e308"); | ||||
|     check(-1.7976931348623157E+308, "-1.797693135e308"); | ||||
|     check<double>(1.7976931348623157E+308, "1.797693135e308"); | ||||
|     check<double>(-1.7976931348623157E+308, "-1.797693135e308"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Big exponent") { | ||||
|     // this test increases coverage of normalize() | ||||
|     check(1e255, "1e255"); | ||||
|     check(1e-255, "1e-255"); | ||||
|     check<double>(1e255, "1e255"); | ||||
|     check<double>(1e-255, "1e-255"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Exponentation when <= 1e-5") { | ||||
|     check(1e-4, "0.0001"); | ||||
|     check(1e-5, "1e-5"); | ||||
|     check<double>(1e-4, "0.0001"); | ||||
|     check<double>(1e-5, "1e-5"); | ||||
|  | ||||
|     check(-1e-4, "-0.0001"); | ||||
|     check(-1e-5, "-1e-5"); | ||||
|     check<double>(-1e-4, "-0.0001"); | ||||
|     check<double>(-1e-5, "-1e-5"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Exponentation when >= 1e7") { | ||||
|     check(9999999.999, "9999999.999"); | ||||
|     check(10000000, "1e7"); | ||||
|     check<double>(9999999.999, "9999999.999"); | ||||
|     check<double>(10000000.0, "1e7"); | ||||
|  | ||||
|     check(-9999999.999, "-9999999.999"); | ||||
|     check(-10000000, "-1e7"); | ||||
|     check<double>(-9999999.999, "-9999999.999"); | ||||
|     check<double>(-10000000.0, "-1e7"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Rounding when too many decimals") { | ||||
|     check(0.000099999999999, "0.0001"); | ||||
|     check(0.0000099999999999, "1e-5"); | ||||
|     check(0.9999999996, "1"); | ||||
|     check<double>(0.000099999999999, "0.0001"); | ||||
|     check<double>(0.0000099999999999, "1e-5"); | ||||
|     check<double>(0.9999999996, "1"); | ||||
|   } | ||||
|  | ||||
|   SECTION("9 decimal places") { | ||||
|     check(0.100000001, "0.100000001"); | ||||
|     check(0.999999999, "0.999999999"); | ||||
|     check<double>(0.100000001, "0.100000001"); | ||||
|     check<double>(0.999999999, "0.999999999"); | ||||
|  | ||||
|     check(9.000000001, "9.000000001"); | ||||
|     check(9.999999999, "9.999999999"); | ||||
|     check<double>(9.000000001, "9.000000001"); | ||||
|     check<double>(9.999999999, "9.999999999"); | ||||
|   } | ||||
|  | ||||
|   SECTION("10 decimal places") { | ||||
|     check(0.1000000001, "0.1"); | ||||
|     check(0.9999999999, "1"); | ||||
|     check<double>(0.1000000001, "0.1"); | ||||
|     check<double>(0.9999999999, "1"); | ||||
|  | ||||
|     check(9.0000000001, "9"); | ||||
|     check(9.9999999999, "10"); | ||||
|     check<double>(9.0000000001, "9"); | ||||
|     check<double>(9.9999999999, "10"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonWriter::writeFloat(float)") { | ||||
|   SECTION("Pi") { | ||||
|     check<float>(3.14159265359f, "3.141593"); | ||||
|   } | ||||
|  | ||||
|   SECTION("999.9") {  // issue #543 | ||||
|     check<float>(999.9f, "999.9"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|  | ||||
| add_executable(MiscTests  | ||||
| 	deprecated.cpp | ||||
| 	FloatParts.cpp | ||||
| 	std_stream.cpp | ||||
| 	std_string.cpp | ||||
| 	StringBuilder.cpp | ||||
|   | ||||
							
								
								
									
										47
									
								
								test/Misc/FloatParts.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								test/Misc/FloatParts.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| // Copyright Benoit Blanchon 2014-2017 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://bblanchon.github.io/ArduinoJson/ | ||||
| // If you like this project, please add a star! | ||||
|  | ||||
| #include <ArduinoJson/Serialization/FloatParts.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| TEST_CASE("FloatParts<double>") { | ||||
|   SECTION("1.7976931348623157E+308") { | ||||
|     FloatParts<double> parts(1.7976931348623157E+308); | ||||
|     REQUIRE(parts.integral == 1); | ||||
|     REQUIRE(parts.decimal == 797693135); | ||||
|     REQUIRE(parts.decimalPlaces == 9); | ||||
|     REQUIRE(parts.exponent == 308); | ||||
|   } | ||||
|  | ||||
|   SECTION("4.94065645841247e-324") { | ||||
|     FloatParts<double> parts(4.94065645841247e-324); | ||||
|     REQUIRE(parts.integral == 4); | ||||
|     REQUIRE(parts.decimal == 940656458); | ||||
|     REQUIRE(parts.decimalPlaces == 9); | ||||
|     REQUIRE(parts.exponent == -324); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("FloatParts<float>") { | ||||
|   SECTION("3.4E+38") { | ||||
|     FloatParts<float> parts(3.4E+38f); | ||||
|     REQUIRE(parts.integral == 3); | ||||
|     REQUIRE(parts.decimal == 4); | ||||
|     REQUIRE(parts.decimalPlaces == 1); | ||||
|     REQUIRE(parts.exponent == 38); | ||||
|   } | ||||
|  | ||||
|   SECTION("1.17549435e−38") { | ||||
|     FloatParts<float> parts(1.17549435e-38f); | ||||
|     REQUIRE(parts.integral == 1); | ||||
|     REQUIRE(parts.decimal == 175494); | ||||
|     REQUIRE(parts.decimalPlaces == 6); | ||||
|     REQUIRE(parts.exponent == -38); | ||||
|   } | ||||
| } | ||||
| @@ -8,7 +8,6 @@ | ||||
| add_executable(PolyfillsTests  | ||||
| 	isFloat.cpp | ||||
| 	isInteger.cpp | ||||
| 	normalize.cpp | ||||
| 	parseFloat.cpp | ||||
| 	parseInteger.cpp | ||||
| ) | ||||
|   | ||||
| @@ -1,43 +0,0 @@ | ||||
| // Copyright Benoit Blanchon 2014-2017 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://bblanchon.github.io/ArduinoJson/ | ||||
| // If you like this project, please add a star! | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/normalize.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Polyfills; | ||||
|  | ||||
| TEST_CASE("normalize<double>()") { | ||||
|   SECTION("1.7976931348623157E+308") { | ||||
|     double value = 1.7976931348623157E+308; | ||||
|     int exp = normalize(value); | ||||
|     REQUIRE(value == Approx(1.7976931348623157)); | ||||
|     REQUIRE(exp == 308); | ||||
|   } | ||||
|  | ||||
|   SECTION("4.94065645841247e-324") { | ||||
|     double value = 4.94065645841247e-324; | ||||
|     int exp = normalize(value); | ||||
|     REQUIRE(value == Approx(4.94065645841247)); | ||||
|     REQUIRE(exp == -324); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("normalize<float>()") { | ||||
|   SECTION("3.4E+38") { | ||||
|     float value = 3.4E+38f; | ||||
|     int exp = normalize(value); | ||||
|     REQUIRE(value == Approx(3.4f)); | ||||
|     REQUIRE(exp == 38); | ||||
|   } | ||||
|  | ||||
|   SECTION("1.17549435e−38") { | ||||
|     float value = 1.17549435e-38f; | ||||
|     int exp = normalize(value); | ||||
|     REQUIRE(value == Approx(1.17549435)); | ||||
|     REQUIRE(exp == -38); | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user