Minh Nguyen / ArduinoJson
Committer:
khaiminhvn
Date:
Fri Mar 19 19:30:50 2021 +0000
Revision:
0:18ba3960b5dd
removed extras

Who changed what in which revision?

UserRevisionLine numberNew contents of line
khaiminhvn 0:18ba3960b5dd 1 // ArduinoJson - arduinojson.org
khaiminhvn 0:18ba3960b5dd 2 // Copyright Benoit Blanchon 2014-2021
khaiminhvn 0:18ba3960b5dd 3 // MIT License
khaiminhvn 0:18ba3960b5dd 4
khaiminhvn 0:18ba3960b5dd 5 #pragma once
khaiminhvn 0:18ba3960b5dd 6
khaiminhvn 0:18ba3960b5dd 7 #include <stddef.h> // for size_t
khaiminhvn 0:18ba3960b5dd 8 #include <stdint.h>
khaiminhvn 0:18ba3960b5dd 9
khaiminhvn 0:18ba3960b5dd 10 #include <ArduinoJson/Configuration.hpp>
khaiminhvn 0:18ba3960b5dd 11 #include <ArduinoJson/Polyfills/alias_cast.hpp>
khaiminhvn 0:18ba3960b5dd 12 #include <ArduinoJson/Polyfills/math.hpp>
khaiminhvn 0:18ba3960b5dd 13 #include <ArduinoJson/Polyfills/preprocessor.hpp>
khaiminhvn 0:18ba3960b5dd 14 #include <ArduinoJson/Polyfills/static_array.hpp>
khaiminhvn 0:18ba3960b5dd 15
khaiminhvn 0:18ba3960b5dd 16 namespace ARDUINOJSON_NAMESPACE {
khaiminhvn 0:18ba3960b5dd 17
khaiminhvn 0:18ba3960b5dd 18 template <typename T, size_t = sizeof(T)>
khaiminhvn 0:18ba3960b5dd 19 struct FloatTraits {};
khaiminhvn 0:18ba3960b5dd 20
khaiminhvn 0:18ba3960b5dd 21 template <typename T>
khaiminhvn 0:18ba3960b5dd 22 struct FloatTraits<T, 8 /*64bits*/> {
khaiminhvn 0:18ba3960b5dd 23 typedef uint64_t mantissa_type;
khaiminhvn 0:18ba3960b5dd 24 static const short mantissa_bits = 52;
khaiminhvn 0:18ba3960b5dd 25 static const mantissa_type mantissa_max =
khaiminhvn 0:18ba3960b5dd 26 (mantissa_type(1) << mantissa_bits) - 1;
khaiminhvn 0:18ba3960b5dd 27
khaiminhvn 0:18ba3960b5dd 28 typedef int16_t exponent_type;
khaiminhvn 0:18ba3960b5dd 29 static const exponent_type exponent_max = 308;
khaiminhvn 0:18ba3960b5dd 30
khaiminhvn 0:18ba3960b5dd 31 template <typename TExponent>
khaiminhvn 0:18ba3960b5dd 32 static T make_float(T m, TExponent e) {
khaiminhvn 0:18ba3960b5dd 33 if (e > 0) {
khaiminhvn 0:18ba3960b5dd 34 for (uint8_t index = 0; e != 0; index++) {
khaiminhvn 0:18ba3960b5dd 35 if (e & 1)
khaiminhvn 0:18ba3960b5dd 36 m *= positiveBinaryPowerOfTen(index);
khaiminhvn 0:18ba3960b5dd 37 e >>= 1;
khaiminhvn 0:18ba3960b5dd 38 }
khaiminhvn 0:18ba3960b5dd 39 } else {
khaiminhvn 0:18ba3960b5dd 40 e = TExponent(-e);
khaiminhvn 0:18ba3960b5dd 41 for (uint8_t index = 0; e != 0; index++) {
khaiminhvn 0:18ba3960b5dd 42 if (e & 1)
khaiminhvn 0:18ba3960b5dd 43 m *= negativeBinaryPowerOfTen(index);
khaiminhvn 0:18ba3960b5dd 44 e >>= 1;
khaiminhvn 0:18ba3960b5dd 45 }
khaiminhvn 0:18ba3960b5dd 46 }
khaiminhvn 0:18ba3960b5dd 47 return m;
khaiminhvn 0:18ba3960b5dd 48 }
khaiminhvn 0:18ba3960b5dd 49
khaiminhvn 0:18ba3960b5dd 50 static T positiveBinaryPowerOfTen(int index) {
khaiminhvn 0:18ba3960b5dd 51 ARDUINOJSON_DEFINE_STATIC_ARRAY( //
khaiminhvn 0:18ba3960b5dd 52 uint32_t, factors,
khaiminhvn 0:18ba3960b5dd 53 ARDUINOJSON_EXPAND18({
khaiminhvn 0:18ba3960b5dd 54 0x40240000, 0x00000000, // 1e1
khaiminhvn 0:18ba3960b5dd 55 0x40590000, 0x00000000, // 1e2
khaiminhvn 0:18ba3960b5dd 56 0x40C38800, 0x00000000, // 1e4
khaiminhvn 0:18ba3960b5dd 57 0x4197D784, 0x00000000, // 1e8
khaiminhvn 0:18ba3960b5dd 58 0x4341C379, 0x37E08000, // 1e16
khaiminhvn 0:18ba3960b5dd 59 0x4693B8B5, 0xB5056E17, // 1e32
khaiminhvn 0:18ba3960b5dd 60 0x4D384F03, 0xE93FF9F5, // 1e64
khaiminhvn 0:18ba3960b5dd 61 0x5A827748, 0xF9301D32, // 1e128
khaiminhvn 0:18ba3960b5dd 62 0x75154FDD, 0x7F73BF3C // 1e256
khaiminhvn 0:18ba3960b5dd 63 }));
khaiminhvn 0:18ba3960b5dd 64 return forge(
khaiminhvn 0:18ba3960b5dd 65 ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
khaiminhvn 0:18ba3960b5dd 66 ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
khaiminhvn 0:18ba3960b5dd 67 }
khaiminhvn 0:18ba3960b5dd 68
khaiminhvn 0:18ba3960b5dd 69 static T negativeBinaryPowerOfTen(int index) {
khaiminhvn 0:18ba3960b5dd 70 ARDUINOJSON_DEFINE_STATIC_ARRAY( //
khaiminhvn 0:18ba3960b5dd 71 uint32_t, factors,
khaiminhvn 0:18ba3960b5dd 72 ARDUINOJSON_EXPAND18({
khaiminhvn 0:18ba3960b5dd 73 0x3FB99999, 0x9999999A, // 1e-1
khaiminhvn 0:18ba3960b5dd 74 0x3F847AE1, 0x47AE147B, // 1e-2
khaiminhvn 0:18ba3960b5dd 75 0x3F1A36E2, 0xEB1C432D, // 1e-4
khaiminhvn 0:18ba3960b5dd 76 0x3E45798E, 0xE2308C3A, // 1e-8
khaiminhvn 0:18ba3960b5dd 77 0x3C9CD2B2, 0x97D889BC, // 1e-16
khaiminhvn 0:18ba3960b5dd 78 0x3949F623, 0xD5A8A733, // 1e-32
khaiminhvn 0:18ba3960b5dd 79 0x32A50FFD, 0x44F4A73D, // 1e-64
khaiminhvn 0:18ba3960b5dd 80 0x255BBA08, 0xCF8C979D, // 1e-128
khaiminhvn 0:18ba3960b5dd 81 0x0AC80628, 0x64AC6F43 // 1e-256
khaiminhvn 0:18ba3960b5dd 82 }));
khaiminhvn 0:18ba3960b5dd 83 return forge(
khaiminhvn 0:18ba3960b5dd 84 ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
khaiminhvn 0:18ba3960b5dd 85 ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
khaiminhvn 0:18ba3960b5dd 86 }
khaiminhvn 0:18ba3960b5dd 87
khaiminhvn 0:18ba3960b5dd 88 static T negativeBinaryPowerOfTenPlusOne(int index) {
khaiminhvn 0:18ba3960b5dd 89 ARDUINOJSON_DEFINE_STATIC_ARRAY( //
khaiminhvn 0:18ba3960b5dd 90 uint32_t, factors,
khaiminhvn 0:18ba3960b5dd 91 ARDUINOJSON_EXPAND18({
khaiminhvn 0:18ba3960b5dd 92 0x3FF00000, 0x00000000, // 1e0
khaiminhvn 0:18ba3960b5dd 93 0x3FB99999, 0x9999999A, // 1e-1
khaiminhvn 0:18ba3960b5dd 94 0x3F50624D, 0xD2F1A9FC, // 1e-3
khaiminhvn 0:18ba3960b5dd 95 0x3E7AD7F2, 0x9ABCAF48, // 1e-7
khaiminhvn 0:18ba3960b5dd 96 0x3CD203AF, 0x9EE75616, // 1e-15
khaiminhvn 0:18ba3960b5dd 97 0x398039D6, 0x65896880, // 1e-31
khaiminhvn 0:18ba3960b5dd 98 0x32DA53FC, 0x9631D10D, // 1e-63
khaiminhvn 0:18ba3960b5dd 99 0x25915445, 0x81B7DEC2, // 1e-127
khaiminhvn 0:18ba3960b5dd 100 0x0AFE07B2, 0x7DD78B14 // 1e-255
khaiminhvn 0:18ba3960b5dd 101 }));
khaiminhvn 0:18ba3960b5dd 102 return forge(
khaiminhvn 0:18ba3960b5dd 103 ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
khaiminhvn 0:18ba3960b5dd 104 ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
khaiminhvn 0:18ba3960b5dd 105 }
khaiminhvn 0:18ba3960b5dd 106
khaiminhvn 0:18ba3960b5dd 107 static T nan() {
khaiminhvn 0:18ba3960b5dd 108 return forge(0x7ff80000, 0x00000000);
khaiminhvn 0:18ba3960b5dd 109 }
khaiminhvn 0:18ba3960b5dd 110
khaiminhvn 0:18ba3960b5dd 111 static T inf() {
khaiminhvn 0:18ba3960b5dd 112 return forge(0x7ff00000, 0x00000000);
khaiminhvn 0:18ba3960b5dd 113 }
khaiminhvn 0:18ba3960b5dd 114
khaiminhvn 0:18ba3960b5dd 115 static T highest() {
khaiminhvn 0:18ba3960b5dd 116 return forge(0x7FEFFFFF, 0xFFFFFFFF);
khaiminhvn 0:18ba3960b5dd 117 }
khaiminhvn 0:18ba3960b5dd 118
khaiminhvn 0:18ba3960b5dd 119 static T lowest() {
khaiminhvn 0:18ba3960b5dd 120 return forge(0xFFEFFFFF, 0xFFFFFFFF);
khaiminhvn 0:18ba3960b5dd 121 }
khaiminhvn 0:18ba3960b5dd 122
khaiminhvn 0:18ba3960b5dd 123 // constructs a double floating point values from its binary representation
khaiminhvn 0:18ba3960b5dd 124 // we use this function to workaround platforms with single precision literals
khaiminhvn 0:18ba3960b5dd 125 // (for example, when -fsingle-precision-constant is passed to GCC)
khaiminhvn 0:18ba3960b5dd 126 static T forge(uint32_t msb, uint32_t lsb) {
khaiminhvn 0:18ba3960b5dd 127 return alias_cast<T>((uint64_t(msb) << 32) | lsb);
khaiminhvn 0:18ba3960b5dd 128 }
khaiminhvn 0:18ba3960b5dd 129 };
khaiminhvn 0:18ba3960b5dd 130
khaiminhvn 0:18ba3960b5dd 131 template <typename T>
khaiminhvn 0:18ba3960b5dd 132 struct FloatTraits<T, 4 /*32bits*/> {
khaiminhvn 0:18ba3960b5dd 133 typedef uint32_t mantissa_type;
khaiminhvn 0:18ba3960b5dd 134 static const short mantissa_bits = 23;
khaiminhvn 0:18ba3960b5dd 135 static const mantissa_type mantissa_max =
khaiminhvn 0:18ba3960b5dd 136 (mantissa_type(1) << mantissa_bits) - 1;
khaiminhvn 0:18ba3960b5dd 137
khaiminhvn 0:18ba3960b5dd 138 typedef int8_t exponent_type;
khaiminhvn 0:18ba3960b5dd 139 static const exponent_type exponent_max = 38;
khaiminhvn 0:18ba3960b5dd 140
khaiminhvn 0:18ba3960b5dd 141 template <typename TExponent>
khaiminhvn 0:18ba3960b5dd 142 static T make_float(T m, TExponent e) {
khaiminhvn 0:18ba3960b5dd 143 if (e > 0) {
khaiminhvn 0:18ba3960b5dd 144 for (uint8_t index = 0; e != 0; index++) {
khaiminhvn 0:18ba3960b5dd 145 if (e & 1)
khaiminhvn 0:18ba3960b5dd 146 m *= positiveBinaryPowerOfTen(index);
khaiminhvn 0:18ba3960b5dd 147 e >>= 1;
khaiminhvn 0:18ba3960b5dd 148 }
khaiminhvn 0:18ba3960b5dd 149 } else {
khaiminhvn 0:18ba3960b5dd 150 e = -e;
khaiminhvn 0:18ba3960b5dd 151 for (uint8_t index = 0; e != 0; index++) {
khaiminhvn 0:18ba3960b5dd 152 if (e & 1)
khaiminhvn 0:18ba3960b5dd 153 m *= negativeBinaryPowerOfTen(index);
khaiminhvn 0:18ba3960b5dd 154 e >>= 1;
khaiminhvn 0:18ba3960b5dd 155 }
khaiminhvn 0:18ba3960b5dd 156 }
khaiminhvn 0:18ba3960b5dd 157 return m;
khaiminhvn 0:18ba3960b5dd 158 }
khaiminhvn 0:18ba3960b5dd 159
khaiminhvn 0:18ba3960b5dd 160 static T positiveBinaryPowerOfTen(int index) {
khaiminhvn 0:18ba3960b5dd 161 ARDUINOJSON_DEFINE_STATIC_ARRAY(
khaiminhvn 0:18ba3960b5dd 162 T, factors,
khaiminhvn 0:18ba3960b5dd 163 ARDUINOJSON_EXPAND6({1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f}));
khaiminhvn 0:18ba3960b5dd 164 return ARDUINOJSON_READ_STATIC_ARRAY(T, factors, index);
khaiminhvn 0:18ba3960b5dd 165 }
khaiminhvn 0:18ba3960b5dd 166
khaiminhvn 0:18ba3960b5dd 167 static T negativeBinaryPowerOfTen(int index) {
khaiminhvn 0:18ba3960b5dd 168 ARDUINOJSON_DEFINE_STATIC_ARRAY(
khaiminhvn 0:18ba3960b5dd 169 T, factors,
khaiminhvn 0:18ba3960b5dd 170 ARDUINOJSON_EXPAND6({1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f}));
khaiminhvn 0:18ba3960b5dd 171 return ARDUINOJSON_READ_STATIC_ARRAY(T, factors, index);
khaiminhvn 0:18ba3960b5dd 172 }
khaiminhvn 0:18ba3960b5dd 173
khaiminhvn 0:18ba3960b5dd 174 static T negativeBinaryPowerOfTenPlusOne(int index) {
khaiminhvn 0:18ba3960b5dd 175 ARDUINOJSON_DEFINE_STATIC_ARRAY(
khaiminhvn 0:18ba3960b5dd 176 T, factors,
khaiminhvn 0:18ba3960b5dd 177 ARDUINOJSON_EXPAND6({1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f}));
khaiminhvn 0:18ba3960b5dd 178 return ARDUINOJSON_READ_STATIC_ARRAY(T, factors, index);
khaiminhvn 0:18ba3960b5dd 179 }
khaiminhvn 0:18ba3960b5dd 180
khaiminhvn 0:18ba3960b5dd 181 static T forge(uint32_t bits) {
khaiminhvn 0:18ba3960b5dd 182 return alias_cast<T>(bits);
khaiminhvn 0:18ba3960b5dd 183 }
khaiminhvn 0:18ba3960b5dd 184
khaiminhvn 0:18ba3960b5dd 185 static T nan() {
khaiminhvn 0:18ba3960b5dd 186 return forge(0x7fc00000);
khaiminhvn 0:18ba3960b5dd 187 }
khaiminhvn 0:18ba3960b5dd 188
khaiminhvn 0:18ba3960b5dd 189 static T inf() {
khaiminhvn 0:18ba3960b5dd 190 return forge(0x7f800000);
khaiminhvn 0:18ba3960b5dd 191 }
khaiminhvn 0:18ba3960b5dd 192
khaiminhvn 0:18ba3960b5dd 193 static T highest() {
khaiminhvn 0:18ba3960b5dd 194 return forge(0x7f7fffff);
khaiminhvn 0:18ba3960b5dd 195 }
khaiminhvn 0:18ba3960b5dd 196
khaiminhvn 0:18ba3960b5dd 197 static T lowest() {
khaiminhvn 0:18ba3960b5dd 198 return forge(0xFf7fffff);
khaiminhvn 0:18ba3960b5dd 199 }
khaiminhvn 0:18ba3960b5dd 200 };
khaiminhvn 0:18ba3960b5dd 201 } // namespace ARDUINOJSON_NAMESPACE