Compare commits

...

7 Commits

19 changed files with 321 additions and 232 deletions

View File

@ -89,9 +89,7 @@ matrix:
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.8.2 BOARD=arduino:avr:uno
- env: SCRIPT=platformio BOARD=uno
- env: SCRIPT=platformio BOARD=due
- env: SCRIPT=platformio BOARD=esp01
#- env: SCRIPT=platformio BOARD=teensy31C
cache:
directories:
- "~/.platformio"

View File

@ -1,6 +1,16 @@
ArduinoJson: change log
=======================
v5.11.1
-------
* Removed dependency on `PGM_P` as Particle 0.6.2 doesn't define it (issue #546)
* 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 "this statement may fall through" [-Wimplicit-fallthrough=] (issue #539)
* Removed `ARDUINOJSON_DOUBLE_IS_64BITS` as it became useless.
* Fixed too many decimals places in float serialization (issue #543)
v5.11.0
-------

View File

@ -118,6 +118,7 @@ Special thanks to the following persons and companies who made generous donation
* Prokhoryatov Alexey <img alt='Russia' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f7-1f1fa.svg' width='18' height='18'>
* Google Inc. <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Charles Haynes <img alt='Australia' src='https://d1j8pt39hxlh3d.cloudfront.net/development/emojione/2.2/989/2546.svg' width='18' height='18'>
* Charles Walker <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
---

View File

@ -1,4 +1,4 @@
version: 5.11.0.{build}
version: 5.11.1.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017

View File

@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "5.11.0",
"version": "5.11.1",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"

View File

@ -1,5 +1,5 @@
name=ArduinoJson
version=5.11.0
version=5.11.1
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.

View File

@ -148,16 +148,6 @@
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
#endif
// how many bits in a double
#ifndef ARDUINOJSON_DOUBLE_IS_64BITS
#if /*GCC*/ (defined(__SIZEOF_DOUBLE__) && __SIZEOF_DOUBLE__ < 8) || \
/*IAR*/ (defined(__DOUBLE__) && __DOUBLE__ < 64)
#define ARDUINOJSON_DOUBLE_IS_64BITS 0
#else
#define ARDUINOJSON_DOUBLE_IS_64BITS 1 // by default support 64-bit
#endif
#endif
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
#endif

View File

@ -1,103 +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"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
int16_t normalize(T& value) {
int16_t powersOf10 = 0;
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
#if ARDUINOJSON_DOUBLE_IS_64BITS
if (value >= 1e256) {
value /= 1e256;
powersOf10 = int16_t(powersOf10 + 256);
}
if (value >= 1e128) {
value /= 1e128;
powersOf10 = int16_t(powersOf10 + 128);
}
if (value >= 1e64) {
value /= 1e64;
powersOf10 = int16_t(powersOf10 + 64);
}
#endif
if (value >= 1e32) {
value /= 1e32;
powersOf10 = int16_t(powersOf10 + 32);
}
if (value >= 1e16) {
value /= 1e16;
powersOf10 = int16_t(powersOf10 + 16);
}
if (value >= 1e8) {
value /= 1e8;
powersOf10 = int16_t(powersOf10 + 8);
}
if (value >= 1e4) {
value /= 1e4;
powersOf10 = int16_t(powersOf10 + 4);
}
if (value >= 1e2) {
value /= 1e2;
powersOf10 = int16_t(powersOf10 + 2);
}
if (value >= 1e1) {
value /= 1e1;
powersOf10 = int16_t(powersOf10 + 1);
}
}
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
#if ARDUINOJSON_DOUBLE_IS_64BITS
if (value < 1e-255) {
value *= 1e256;
powersOf10 = int16_t(powersOf10 - 256);
}
if (value < 1e-127) {
value *= 1e128;
powersOf10 = int16_t(powersOf10 - 128);
}
if (value < 1e-63) {
value *= 1e64;
powersOf10 = int16_t(powersOf10 - 64);
}
#endif
if (value < 1e-31) {
value *= 1e32;
powersOf10 = int16_t(powersOf10 - 32);
}
if (value < 1e-15) {
value *= 1e16;
powersOf10 = int16_t(powersOf10 - 16);
}
if (value < 1e-7) {
value *= 1e8;
powersOf10 = int16_t(powersOf10 - 8);
}
if (value < 1e-3) {
value *= 1e4;
powersOf10 = int16_t(powersOf10 - 4);
}
if (value < 1e-1) {
value *= 1e2;
powersOf10 = int16_t(powersOf10 - 2);
}
if (value < 1e0) {
value *= 1e1;
powersOf10 = int16_t(powersOf10 - 1);
}
}
return powersOf10;
}
}
}

View File

@ -26,8 +26,11 @@ inline T parseFloat(const char* s) {
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
}
if (*s == 't') return 1; // true

View File

@ -26,6 +26,8 @@ T parseInteger(const char *s) {
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;

View 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;
}
};
}
}

View File

@ -9,12 +9,9 @@
#include <stdint.h>
#include "../Data/Encoding.hpp"
#include "../Data/JsonFloat.hpp"
#include "../Data/JsonInteger.hpp"
#include "../Polyfills/attributes.hpp"
#include "../Polyfills/math.hpp"
#include "../Polyfills/normalize.hpp"
#include "../TypeTraits/FloatTraits.hpp"
#include "../Serialization/FloatParts.hpp"
namespace ArduinoJson {
namespace Internals {
@ -28,10 +25,6 @@ namespace Internals {
// indentation.
template <typename Print>
class JsonWriter {
static const uint8_t maxDecimalPlaces = sizeof(JsonFloat) >= 8 ? 9 : 6;
static const uint32_t maxDecimalPart =
sizeof(JsonFloat) >= 8 ? 1000000000 : 1000000;
public:
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 (value < 0.0) {
@ -97,28 +91,27 @@ class JsonWriter {
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
uint32_t integralPart, decimalPart;
int16_t powersOf10;
splitFloat(value, integralPart, decimalPart, powersOf10);
FloatParts<TFloat> parts(value);
writeInteger(integralPart);
if (decimalPart) writeDecimals(decimalPart, maxDecimalPlaces);
writeInteger(parts.integral);
if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces);
if (powersOf10 < 0) {
if (parts.exponent < 0) {
writeRaw("e-");
writeInteger(-powersOf10);
writeInteger(-parts.exponent);
}
if (powersOf10 > 0) {
if (parts.exponent > 0) {
writeRaw('e');
writeInteger(powersOf10);
writeInteger(parts.exponent);
}
}
template <typename UInt>
void writeInteger(UInt value) {
char buffer[22];
char *ptr = buffer + sizeof(buffer) - 1;
char *end = buffer + sizeof(buffer) - 1;
char *ptr = end;
*ptr = 0;
do {
@ -130,15 +123,9 @@ class JsonWriter {
}
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
// terminator
char buffer[maxDecimalPlaces + 2];
char buffer[16];
char *ptr = buffer + sizeof(buffer) - 1;
// write the string in reverse order
@ -166,30 +153,6 @@ class JsonWriter {
private:
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;
}
}
}
};
}
}

View File

@ -34,15 +34,15 @@ struct StringTraits<const __FlashStringHelper*, void> {
};
static bool equals(const __FlashStringHelper* str, const char* expected) {
return strcmp_P(expected, (PGM_P)str) == 0;
return strcmp_P(expected, (const char*)str) == 0;
}
template <typename Buffer>
static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen_P((PGM_P)str) + 1;
size_t size = strlen_P((const char*)str) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy_P(dup, (PGM_P)str, size);
if (dup != NULL) memcpy_P(dup, (const char*)str, size);
return static_cast<char*>(dup);
}

View File

@ -18,7 +18,6 @@ namespace TypeTraits {
template <typename T, size_t = sizeof(T)>
struct FloatTraits {};
#if ARDUINOJSON_DOUBLE_IS_64BITS
template <typename T>
struct FloatTraits<T, 8 /*64bits*/> {
typedef int64_t mantissa_type;
@ -31,29 +30,65 @@ struct FloatTraits<T, 8 /*64bits*/> {
template <typename TExponent>
static T make_float(T m, TExponent e) {
if (e >= 0)
return m * (e & 1 ? 1e1 : 1) * (e & 2 ? 1e2 : 1) * (e & 4 ? 1e4 : 1) *
(e & 8 ? 1e8 : 1) * (e & 16 ? 1e16 : 1) * (e & 32 ? 1e32 : 1) *
(e & 64 ? 1e64 : 1) * (e & 128 ? 1e128 : 1) *
(e & 256 ? 1e256 : 1);
e = TExponent(-e);
return m * (e & 1 ? 1e-1 : 1) * (e & 2 ? 1e-2 : 1) * (e & 4 ? 1e-4 : 1) *
(e & 8 ? 1e-8 : 1) * (e & 16 ? 1e-16 : 1) * (e & 32 ? 1e-32 : 1) *
(e & 64 ? 1e-64 : 1) * (e & 128 ? 1e-128 : 1) *
(e & 256 ? 1e-256 : 1);
if (e > 0) {
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= positiveBinaryPowerOfTen(index);
e >>= 1;
}
} else {
e = TExponent(-e);
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= negativeBinaryPowerOfTen(index);
e >>= 1;
}
}
return m;
}
static T positiveBinaryPowerOfTen(int index) {
static T factors[] = {
1e1, 1e2, 1e4, 1e8, 1e16, 1e32,
// workaround to support platforms with single precision literals
forge(0x4D384F03, 0xE93FF9F5), forge(0x5A827748, 0xF9301D32),
forge(0x75154FDD, 0x7F73BF3C)};
return factors[index];
}
static T negativeBinaryPowerOfTen(int index) {
static T factors[] = {
1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32,
// workaround to support platforms with single precision literals
forge(0x32A50FFD, 0x44F4A73D), forge(0x255BBA08, 0xCF8C979D),
forge(0x0AC80628, 0x64AC6F43)};
return factors[index];
}
static T negativeBinaryPowerOfTenPlusOne(int index) {
static T factors[] = {
1e0, 1e-1, 1e-3, 1e-7, 1e-15, 1e-31,
// workaround to support platforms with single precision literals
forge(0x32DA53FC, 0x9631D10D), forge(0x25915445, 0x81B7DEC2),
forge(0x0AFE07B2, 0x7DD78B14)};
return factors[index];
}
static T nan() {
uint64_t x = uint64_t(0x7ff8) << 48;
return *reinterpret_cast<T*>(&x);
return forge(0x7ff80000, 0x00000000);
}
static T inf() {
uint64_t x = uint64_t(0x7ff0) << 48;
return *reinterpret_cast<T*>(&x);
return forge(0x7ff00000, 0x00000000);
}
static T forge(uint32_t msb, uint32_t lsb) {
union {
uint64_t integerBits;
T floatBits;
};
integerBits = (uint64_t(msb) << 32) | lsb;
return floatBits;
}
};
#endif
template <typename T>
struct FloatTraits<T, 4 /*32bits*/> {
@ -67,22 +102,51 @@ struct FloatTraits<T, 4 /*32bits*/> {
template <typename TExponent>
static T make_float(T m, TExponent e) {
if (e > 0)
return m * (e & 1 ? 1e1f : 1) * (e & 2 ? 1e2f : 1) * (e & 4 ? 1e4f : 1) *
(e & 8 ? 1e8f : 1) * (e & 16 ? 1e16f : 1) * (e & 32 ? 1e32f : 1);
e = -e;
return m * (e & 1 ? 1e-1f : 1) * (e & 2 ? 1e-2f : 1) * (e & 4 ? 1e-4f : 1) *
(e & 8 ? 1e-8f : 1) * (e & 16 ? 1e-16f : 1) * (e & 32 ? 1e-32f : 1);
if (e > 0) {
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= positiveBinaryPowerOfTen(index);
e >>= 1;
}
} else {
e = -e;
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= negativeBinaryPowerOfTen(index);
e >>= 1;
}
}
return m;
}
static T positiveBinaryPowerOfTen(int index) {
static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f};
return factors[index];
}
static T negativeBinaryPowerOfTen(int index) {
static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f};
return factors[index];
}
static T negativeBinaryPowerOfTenPlusOne(int index) {
static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f};
return factors[index];
}
static T forge(uint32_t bits) {
union {
uint32_t integerBits;
T floatBits;
};
integerBits = bits;
return floatBits;
}
static T nan() {
uint32_t x = 0x7fc00000;
return *reinterpret_cast<T*>(&x);
return forge(0x7fc00000);
}
static T inf() {
uint32_t x = 0x7f800000;
return *reinterpret_cast<T*>(&x);
return forge(0x7f800000);
}
};
}

View File

@ -19,13 +19,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
-Wformat=2
-Winit-self
-Wmissing-include-dirs
-Wparentheses
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wparentheses
-Wredundant-decls
-Wshadow
-Wsign-promo
-Wstrict-aliasing
-Wstrict-overflow=5
-Wundef
)

View File

@ -10,5 +10,12 @@ add_executable(IntegrationTests
round_trip.cpp
)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(IntegrationTests
PUBLIC
-fsingle-precision-constant # issue 544
)
endif()
target_link_libraries(IntegrationTests catch)
add_test(IntegrationTests IntegrationTests)

View File

@ -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");
}
}

View File

@ -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
View 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.17549435e38") {
FloatParts<float> parts(1.17549435e-38f);
REQUIRE(parts.integral == 1);
REQUIRE(parts.decimal == 175494);
REQUIRE(parts.decimalPlaces == 6);
REQUIRE(parts.exponent == -38);
}
}