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