Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
src/ArduinoJson/Numbers/FloatTraits.hpp@0:18ba3960b5dd, 2021-03-19 (annotated)
- Committer:
- khaiminhvn
- Date:
- Fri Mar 19 19:30:50 2021 +0000
- Revision:
- 0:18ba3960b5dd
removed extras
Who changed what in which revision?
| User | Revision | Line number | New 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 |