forked from bblanchon/ArduinoJson
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