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:
		| @@ -8,6 +8,7 @@ HEAD | |||||||
| * Fixed warning "dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]" | * Fixed warning "dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]" | ||||||
| * Fixed warning "floating constant exceeds range of 'float' [-Woverflow]" (issue #544) | * Fixed warning "floating constant exceeds range of 'float' [-Woverflow]" (issue #544) | ||||||
| * Removed `ARDUINOJSON_DOUBLE_IS_64BITS` as it became useless. | * Removed `ARDUINOJSON_DOUBLE_IS_64BITS` as it became useless. | ||||||
|  | * Fixed too many decimals places in float serialization (issue #543) | ||||||
|  |  | ||||||
| v5.11.0 | v5.11.0 | ||||||
| ------- | ------- | ||||||
|   | |||||||
| @@ -1,46 +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! |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "../Configuration.hpp" |  | ||||||
| #include "../TypeTraits/FloatTraits.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { |  | ||||||
| namespace Polyfills { |  | ||||||
| template <typename T> |  | ||||||
| int16_t normalize(T& value) { |  | ||||||
|   using namespace TypeTraits; |  | ||||||
|   int16_t powersOf10 = 0; |  | ||||||
|  |  | ||||||
|   int8_t index = sizeof(T) == 8 ? 8 : 5; |  | ||||||
|   int bit = 1 << index; |  | ||||||
|  |  | ||||||
|   if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) { |  | ||||||
|     for (; index >= 0; index--) { |  | ||||||
|       if (value >= FloatTraits<T>::positiveBinaryPowerOfTen(index)) { |  | ||||||
|         value *= FloatTraits<T>::negativeBinaryPowerOfTen(index); |  | ||||||
|         powersOf10 = int16_t(powersOf10 + bit); |  | ||||||
|       } |  | ||||||
|       bit >>= 1; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) { |  | ||||||
|     for (; index >= 0; index--) { |  | ||||||
|       if (value < FloatTraits<T>::negativeBinaryPowerOfTenPlusOne(index)) { |  | ||||||
|         value *= FloatTraits<T>::positiveBinaryPowerOfTen(index); |  | ||||||
|         powersOf10 = int16_t(powersOf10 - bit); |  | ||||||
|       } |  | ||||||
|       bit >>= 1; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return powersOf10; |  | ||||||
| } |  | ||||||
| } |  | ||||||
| } |  | ||||||
							
								
								
									
										94
									
								
								src/ArduinoJson/Serialization/FloatParts.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/ArduinoJson/Serialization/FloatParts.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2017 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://bblanchon.github.io/ArduinoJson/ | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "../Configuration.hpp" | ||||||
|  | #include "../Polyfills/math.hpp" | ||||||
|  | #include "../TypeTraits/FloatTraits.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename TFloat> | ||||||
|  | struct FloatParts { | ||||||
|  |   uint32_t integral; | ||||||
|  |   uint32_t decimal; | ||||||
|  |   int16_t exponent; | ||||||
|  |   int8_t decimalPlaces; | ||||||
|  |  | ||||||
|  |   FloatParts(TFloat value) { | ||||||
|  |     const uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000; | ||||||
|  |  | ||||||
|  |     exponent = normalize(value); | ||||||
|  |  | ||||||
|  |     integral = uint32_t(value); | ||||||
|  |     TFloat remainder = value - TFloat(integral); | ||||||
|  |  | ||||||
|  |     remainder *= maxDecimalPart; | ||||||
|  |     decimal = uint32_t(remainder); | ||||||
|  |     remainder = remainder - TFloat(decimal); | ||||||
|  |  | ||||||
|  |     // rounding: | ||||||
|  |     // increment by 1 if remainder >= 0.5 | ||||||
|  |     decimal += uint32_t(remainder * 2); | ||||||
|  |     if (decimal >= maxDecimalPart) { | ||||||
|  |       decimal = 0; | ||||||
|  |       integral++; | ||||||
|  |       if (exponent && integral >= 10) { | ||||||
|  |         exponent++; | ||||||
|  |         integral = 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6; | ||||||
|  |  | ||||||
|  |     // recude number of decimal places by the number of integral places | ||||||
|  |     for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) { | ||||||
|  |       decimal /= 10; | ||||||
|  |       decimalPlaces--; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // remove trailing zeros | ||||||
|  |     while (decimal % 10 == 0 && decimalPlaces > 0) { | ||||||
|  |       decimal /= 10; | ||||||
|  |       decimalPlaces--; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static int16_t normalize(TFloat& value) { | ||||||
|  |     typedef TypeTraits::FloatTraits<TFloat> traits; | ||||||
|  |     int16_t powersOf10 = 0; | ||||||
|  |  | ||||||
|  |     int8_t index = sizeof(TFloat) == 8 ? 8 : 5; | ||||||
|  |     int bit = 1 << index; | ||||||
|  |  | ||||||
|  |     if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) { | ||||||
|  |       for (; index >= 0; index--) { | ||||||
|  |         if (value >= traits::positiveBinaryPowerOfTen(index)) { | ||||||
|  |           value *= traits::negativeBinaryPowerOfTen(index); | ||||||
|  |           powersOf10 = int16_t(powersOf10 + bit); | ||||||
|  |         } | ||||||
|  |         bit >>= 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) { | ||||||
|  |       for (; index >= 0; index--) { | ||||||
|  |         if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) { | ||||||
|  |           value *= traits::positiveBinaryPowerOfTen(index); | ||||||
|  |           powersOf10 = int16_t(powersOf10 - bit); | ||||||
|  |         } | ||||||
|  |         bit >>= 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return powersOf10; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | } | ||||||
| @@ -9,12 +9,9 @@ | |||||||
|  |  | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include "../Data/Encoding.hpp" | #include "../Data/Encoding.hpp" | ||||||
| #include "../Data/JsonFloat.hpp" |  | ||||||
| #include "../Data/JsonInteger.hpp" | #include "../Data/JsonInteger.hpp" | ||||||
| #include "../Polyfills/attributes.hpp" | #include "../Polyfills/attributes.hpp" | ||||||
| #include "../Polyfills/math.hpp" | #include "../Serialization/FloatParts.hpp" | ||||||
| #include "../Polyfills/normalize.hpp" |  | ||||||
| #include "../TypeTraits/FloatTraits.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
| @@ -28,10 +25,6 @@ namespace Internals { | |||||||
| // indentation. | // indentation. | ||||||
| template <typename Print> | template <typename Print> | ||||||
| class JsonWriter { | class JsonWriter { | ||||||
|   static const uint8_t maxDecimalPlaces = sizeof(JsonFloat) >= 8 ? 9 : 6; |  | ||||||
|   static const uint32_t maxDecimalPart = |  | ||||||
|       sizeof(JsonFloat) >= 8 ? 1000000000 : 1000000; |  | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} |   explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} | ||||||
|  |  | ||||||
| @@ -87,7 +80,8 @@ class JsonWriter { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeFloat(JsonFloat value) { |   template <typename TFloat> | ||||||
|  |   void writeFloat(TFloat value) { | ||||||
|     if (Polyfills::isNaN(value)) return writeRaw("NaN"); |     if (Polyfills::isNaN(value)) return writeRaw("NaN"); | ||||||
|  |  | ||||||
|     if (value < 0.0) { |     if (value < 0.0) { | ||||||
| @@ -97,28 +91,27 @@ class JsonWriter { | |||||||
|  |  | ||||||
|     if (Polyfills::isInfinity(value)) return writeRaw("Infinity"); |     if (Polyfills::isInfinity(value)) return writeRaw("Infinity"); | ||||||
|  |  | ||||||
|     uint32_t integralPart, decimalPart; |     FloatParts<TFloat> parts(value); | ||||||
|     int16_t powersOf10; |  | ||||||
|     splitFloat(value, integralPart, decimalPart, powersOf10); |  | ||||||
|  |  | ||||||
|     writeInteger(integralPart); |     writeInteger(parts.integral); | ||||||
|     if (decimalPart) writeDecimals(decimalPart, maxDecimalPlaces); |     if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces); | ||||||
|  |  | ||||||
|     if (powersOf10 < 0) { |     if (parts.exponent < 0) { | ||||||
|       writeRaw("e-"); |       writeRaw("e-"); | ||||||
|       writeInteger(-powersOf10); |       writeInteger(-parts.exponent); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (powersOf10 > 0) { |     if (parts.exponent > 0) { | ||||||
|       writeRaw('e'); |       writeRaw('e'); | ||||||
|       writeInteger(powersOf10); |       writeInteger(parts.exponent); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename UInt> |   template <typename UInt> | ||||||
|   void writeInteger(UInt value) { |   void writeInteger(UInt value) { | ||||||
|     char buffer[22]; |     char buffer[22]; | ||||||
|     char *ptr = buffer + sizeof(buffer) - 1; |     char *end = buffer + sizeof(buffer) - 1; | ||||||
|  |     char *ptr = end; | ||||||
|  |  | ||||||
|     *ptr = 0; |     *ptr = 0; | ||||||
|     do { |     do { | ||||||
| @@ -130,15 +123,9 @@ class JsonWriter { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeDecimals(uint32_t value, int8_t width) { |   void writeDecimals(uint32_t value, int8_t width) { | ||||||
|     // remove trailing zeros |  | ||||||
|     while (value % 10 == 0 && width > 0) { |  | ||||||
|       value /= 10; |  | ||||||
|       width--; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // buffer should be big enough for all digits, the dot and the null |     // buffer should be big enough for all digits, the dot and the null | ||||||
|     // terminator |     // terminator | ||||||
|     char buffer[maxDecimalPlaces + 2]; |     char buffer[16]; | ||||||
|     char *ptr = buffer + sizeof(buffer) - 1; |     char *ptr = buffer + sizeof(buffer) - 1; | ||||||
|  |  | ||||||
|     // write the string in reverse order |     // write the string in reverse order | ||||||
| @@ -166,30 +153,6 @@ class JsonWriter { | |||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   JsonWriter &operator=(const JsonWriter &);  // cannot be assigned |   JsonWriter &operator=(const JsonWriter &);  // cannot be assigned | ||||||
|  |  | ||||||
|   void splitFloat(JsonFloat value, uint32_t &integralPart, |  | ||||||
|                   uint32_t &decimalPart, int16_t &powersOf10) { |  | ||||||
|     powersOf10 = Polyfills::normalize(value); |  | ||||||
|  |  | ||||||
|     integralPart = uint32_t(value); |  | ||||||
|     JsonFloat remainder = value - JsonFloat(integralPart); |  | ||||||
|  |  | ||||||
|     remainder *= maxDecimalPart; |  | ||||||
|     decimalPart = uint32_t(remainder); |  | ||||||
|     remainder = remainder - JsonFloat(decimalPart); |  | ||||||
|  |  | ||||||
|     // rounding: |  | ||||||
|     // increment by 1 if remainder >= 0.5 |  | ||||||
|     decimalPart += uint32_t(remainder * 2); |  | ||||||
|     if (decimalPart >= maxDecimalPart) { |  | ||||||
|       decimalPart = 0; |  | ||||||
|       integralPart++; |  | ||||||
|       if (powersOf10 && integralPart >= 10) { |  | ||||||
|         powersOf10++; |  | ||||||
|         integralPart = 1; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,7 +14,8 @@ | |||||||
|  |  | ||||||
| using namespace ArduinoJson::Internals; | 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; |   std::string output; | ||||||
|   DynamicStringBuilder<std::string> sb(output); |   DynamicStringBuilder<std::string> sb(output); | ||||||
|   JsonWriter<DynamicStringBuilder<std::string> > writer(sb); |   JsonWriter<DynamicStringBuilder<std::string> > writer(sb); | ||||||
| @@ -23,83 +24,93 @@ void check(double input, const std::string& expected) { | |||||||
|   CHECK(expected == output); |   CHECK(expected == output); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST_CASE("JsonWriter::writeFloat()") { | TEST_CASE("JsonWriter::writeFloat(double)") { | ||||||
|   SECTION("Pi") { |   SECTION("Pi") { | ||||||
|     check(3.14159265359, "3.141592654"); |     check<double>(3.14159265359, "3.141592654"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Signaling NaN") { |   SECTION("Signaling NaN") { | ||||||
|     double nan = std::numeric_limits<double>::signaling_NaN(); |     double nan = std::numeric_limits<double>::signaling_NaN(); | ||||||
|     check(nan, "NaN"); |     check<double>(nan, "NaN"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Quiet NaN") { |   SECTION("Quiet NaN") { | ||||||
|     double nan = std::numeric_limits<double>::quiet_NaN(); |     double nan = std::numeric_limits<double>::quiet_NaN(); | ||||||
|     check(nan, "NaN"); |     check<double>(nan, "NaN"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Infinity") { |   SECTION("Infinity") { | ||||||
|     double inf = std::numeric_limits<double>::infinity(); |     double inf = std::numeric_limits<double>::infinity(); | ||||||
|     check(inf, "Infinity"); |     check<double>(inf, "Infinity"); | ||||||
|     check(-inf, "-Infinity"); |     check<double>(-inf, "-Infinity"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Zero") { |   SECTION("Zero") { | ||||||
|     check(0.0, "0"); |     check<double>(0.0, "0"); | ||||||
|     check(-0.0, "0"); |     check<double>(-0.0, "0"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Espilon") { |   SECTION("Espilon") { | ||||||
|     check(2.2250738585072014E-308, "2.225073859e-308"); |     check<double>(2.2250738585072014E-308, "2.225073859e-308"); | ||||||
|     check(-2.2250738585072014E-308, "-2.225073859e-308"); |     check<double>(-2.2250738585072014E-308, "-2.225073859e-308"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Max double") { |   SECTION("Max double") { | ||||||
|     check(1.7976931348623157E+308, "1.797693135e308"); |     check<double>(1.7976931348623157E+308, "1.797693135e308"); | ||||||
|     check(-1.7976931348623157E+308, "-1.797693135e308"); |     check<double>(-1.7976931348623157E+308, "-1.797693135e308"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Big exponent") { |   SECTION("Big exponent") { | ||||||
|     // this test increases coverage of normalize() |     // this test increases coverage of normalize() | ||||||
|     check(1e255, "1e255"); |     check<double>(1e255, "1e255"); | ||||||
|     check(1e-255, "1e-255"); |     check<double>(1e-255, "1e-255"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Exponentation when <= 1e-5") { |   SECTION("Exponentation when <= 1e-5") { | ||||||
|     check(1e-4, "0.0001"); |     check<double>(1e-4, "0.0001"); | ||||||
|     check(1e-5, "1e-5"); |     check<double>(1e-5, "1e-5"); | ||||||
|  |  | ||||||
|     check(-1e-4, "-0.0001"); |     check<double>(-1e-4, "-0.0001"); | ||||||
|     check(-1e-5, "-1e-5"); |     check<double>(-1e-5, "-1e-5"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Exponentation when >= 1e7") { |   SECTION("Exponentation when >= 1e7") { | ||||||
|     check(9999999.999, "9999999.999"); |     check<double>(9999999.999, "9999999.999"); | ||||||
|     check(10000000, "1e7"); |     check<double>(10000000.0, "1e7"); | ||||||
|  |  | ||||||
|     check(-9999999.999, "-9999999.999"); |     check<double>(-9999999.999, "-9999999.999"); | ||||||
|     check(-10000000, "-1e7"); |     check<double>(-10000000.0, "-1e7"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Rounding when too many decimals") { |   SECTION("Rounding when too many decimals") { | ||||||
|     check(0.000099999999999, "0.0001"); |     check<double>(0.000099999999999, "0.0001"); | ||||||
|     check(0.0000099999999999, "1e-5"); |     check<double>(0.0000099999999999, "1e-5"); | ||||||
|     check(0.9999999996, "1"); |     check<double>(0.9999999996, "1"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("9 decimal places") { |   SECTION("9 decimal places") { | ||||||
|     check(0.100000001, "0.100000001"); |     check<double>(0.100000001, "0.100000001"); | ||||||
|     check(0.999999999, "0.999999999"); |     check<double>(0.999999999, "0.999999999"); | ||||||
|  |  | ||||||
|     check(9.000000001, "9.000000001"); |     check<double>(9.000000001, "9.000000001"); | ||||||
|     check(9.999999999, "9.999999999"); |     check<double>(9.999999999, "9.999999999"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("10 decimal places") { |   SECTION("10 decimal places") { | ||||||
|     check(0.1000000001, "0.1"); |     check<double>(0.1000000001, "0.1"); | ||||||
|     check(0.9999999999, "1"); |     check<double>(0.9999999999, "1"); | ||||||
|  |  | ||||||
|     check(9.0000000001, "9"); |     check<double>(9.0000000001, "9"); | ||||||
|     check(9.9999999999, "10"); |     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  | add_executable(MiscTests  | ||||||
| 	deprecated.cpp | 	deprecated.cpp | ||||||
|  | 	FloatParts.cpp | ||||||
| 	std_stream.cpp | 	std_stream.cpp | ||||||
| 	std_string.cpp | 	std_string.cpp | ||||||
| 	StringBuilder.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  | add_executable(PolyfillsTests  | ||||||
| 	isFloat.cpp | 	isFloat.cpp | ||||||
| 	isInteger.cpp | 	isInteger.cpp | ||||||
| 	normalize.cpp |  | ||||||
| 	parseFloat.cpp | 	parseFloat.cpp | ||||||
| 	parseInteger.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