• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 3780565998

pending completion
3780565998

push

github

Benoit Blanchon
Remove support for naked `char` (was deprecated since 6.18.0)

3371 of 3387 relevant lines covered (99.53%)

6014.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.55
/src/ArduinoJson/Numbers/FloatTraits.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2022, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <stddef.h>  // for size_t
8
#include <stdint.h>
9

10
#include <ArduinoJson/Configuration.hpp>
11
#include <ArduinoJson/Polyfills/alias_cast.hpp>
12
#include <ArduinoJson/Polyfills/math.hpp>
13
#include <ArduinoJson/Polyfills/preprocessor.hpp>
14
#include <ArduinoJson/Polyfills/static_array.hpp>
15
#include <ArduinoJson/Polyfills/type_traits.hpp>
16

17
namespace ARDUINOJSON_NAMESPACE {
18

19
template <typename T, size_t = sizeof(T)>
20
struct FloatTraits {};
21

22
template <typename T>
23
struct FloatTraits<T, 8 /*64bits*/> {
24
  typedef uint64_t mantissa_type;
25
  static const short mantissa_bits = 52;
26
  static const mantissa_type mantissa_max =
27
      (mantissa_type(1) << mantissa_bits) - 1;
28

29
  typedef int16_t exponent_type;
30
  static const exponent_type exponent_max = 308;
31

32
  template <typename TExponent>
33
  static T make_float(T m, TExponent e) {
34
    if (e > 0) {
35
      for (uint8_t index = 0; e != 0; index++) {
36
        if (e & 1)
37
          m *= positiveBinaryPowerOfTen(index);
38
        e >>= 1;
39
      }
40
    } else {
41
      e = TExponent(-e);
42
      for (uint8_t index = 0; e != 0; index++) {
43
        if (e & 1)
44
          m *= negativeBinaryPowerOfTen(index);
45
        e >>= 1;
46
      }
47
    }
48
    return m;
49
  }
50

51
  static T positiveBinaryPowerOfTen(int index) {
52
    ARDUINOJSON_DEFINE_STATIC_ARRAY(  //
53
        uint32_t, factors,
54
        ARDUINOJSON_EXPAND18({
55
            0x40240000, 0x00000000,  // 1e1
56
            0x40590000, 0x00000000,  // 1e2
57
            0x40C38800, 0x00000000,  // 1e4
58
            0x4197D784, 0x00000000,  // 1e8
59
            0x4341C379, 0x37E08000,  // 1e16
60
            0x4693B8B5, 0xB5056E17,  // 1e32
61
            0x4D384F03, 0xE93FF9F5,  // 1e64
62
            0x5A827748, 0xF9301D32,  // 1e128
63
            0x75154FDD, 0x7F73BF3C   // 1e256
64
        }));
65
    return forge(
66
        ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
67
        ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
68
  }
69

70
  static T negativeBinaryPowerOfTen(int index) {
71
    ARDUINOJSON_DEFINE_STATIC_ARRAY(  //
72
        uint32_t, factors,
73
        ARDUINOJSON_EXPAND18({
74
            0x3FB99999, 0x9999999A,  // 1e-1
75
            0x3F847AE1, 0x47AE147B,  // 1e-2
76
            0x3F1A36E2, 0xEB1C432D,  // 1e-4
77
            0x3E45798E, 0xE2308C3A,  // 1e-8
78
            0x3C9CD2B2, 0x97D889BC,  // 1e-16
79
            0x3949F623, 0xD5A8A733,  // 1e-32
80
            0x32A50FFD, 0x44F4A73D,  // 1e-64
81
            0x255BBA08, 0xCF8C979D,  // 1e-128
82
            0x0AC80628, 0x64AC6F43   // 1e-256
83
        }));
84
    return forge(
85
        ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
86
        ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
87
  }
88

89
  static T negativeBinaryPowerOfTenPlusOne(int index) {
90
    ARDUINOJSON_DEFINE_STATIC_ARRAY(  //
91
        uint32_t, factors,
92
        ARDUINOJSON_EXPAND18({
93
            0x3FF00000, 0x00000000,  // 1e0
94
            0x3FB99999, 0x9999999A,  // 1e-1
95
            0x3F50624D, 0xD2F1A9FC,  // 1e-3
96
            0x3E7AD7F2, 0x9ABCAF48,  // 1e-7
97
            0x3CD203AF, 0x9EE75616,  // 1e-15
98
            0x398039D6, 0x65896880,  // 1e-31
99
            0x32DA53FC, 0x9631D10D,  // 1e-63
100
            0x25915445, 0x81B7DEC2,  // 1e-127
101
            0x0AFE07B2, 0x7DD78B14   // 1e-255
102
        }));
103
    return forge(
104
        ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
105
        ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
106
  }
107

108
  static T nan() {
109
    return forge(0x7ff80000, 0x00000000);
110
  }
111

112
  static T inf() {
113
    return forge(0x7ff00000, 0x00000000);
114
  }
115

116
  static T highest() {
117
    return forge(0x7FEFFFFF, 0xFFFFFFFF);
118
  }
119

120
  template <typename TOut>  // int64_t
121
  static T highest_for(
122
      typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
123
                             sizeof(TOut) == 8,
124
                         signed>::type* = 0) {
125
    return forge(0x43DFFFFF, 0xFFFFFFFF);  //  9.2233720368547748e+18
126
  }
127

128
  template <typename TOut>  // uint64_t
129
  static T highest_for(
130
      typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
131
                             sizeof(TOut) == 8,
132
                         unsigned>::type* = 0) {
133
    return forge(0x43EFFFFF, 0xFFFFFFFF);  //  1.8446744073709549568e+19
134
  }
135

136
  static T lowest() {
137
    return forge(0xFFEFFFFF, 0xFFFFFFFF);
138
  }
139

140
  // constructs a double floating point values from its binary representation
141
  // we use this function to workaround platforms with single precision literals
142
  // (for example, when -fsingle-precision-constant is passed to GCC)
143
  static T forge(uint32_t msb, uint32_t lsb) {
144
    return alias_cast<T>((uint64_t(msb) << 32) | lsb);
145
  }
146
};
147

148
template <typename T>
149
struct FloatTraits<T, 4 /*32bits*/> {
150
  typedef uint32_t mantissa_type;
151
  static const short mantissa_bits = 23;
152
  static const mantissa_type mantissa_max =
153
      (mantissa_type(1) << mantissa_bits) - 1;
154

155
  typedef int8_t exponent_type;
156
  static const exponent_type exponent_max = 38;
157

158
  template <typename TExponent>
159
  static T make_float(T m, TExponent e) {
160
    if (e > 0) {
161
      for (uint8_t index = 0; e != 0; index++) {
162
        if (e & 1)
163
          m *= positiveBinaryPowerOfTen(index);
164
        e >>= 1;
165
      }
166
    } else {
167
      e = -e;
168
      for (uint8_t index = 0; e != 0; index++) {
169
        if (e & 1)
170
          m *= negativeBinaryPowerOfTen(index);
171
        e >>= 1;
172
      }
173
    }
174
    return m;
175
  }
176

177
  static T positiveBinaryPowerOfTen(int index) {
178
    ARDUINOJSON_DEFINE_STATIC_ARRAY(uint32_t, factors,
179
                                    ARDUINOJSON_EXPAND6({
180
                                        0x41200000,  // 1e1f
181
                                        0x42c80000,  // 1e2f
182
                                        0x461c4000,  // 1e4f
183
                                        0x4cbebc20,  // 1e8f
184
                                        0x5a0e1bca,  // 1e16f
185
                                        0x749dc5ae   // 1e32f
186
                                    }));
187
    return forge(ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, index));
188
  }
189

190
  static T negativeBinaryPowerOfTen(int index) {
191
    ARDUINOJSON_DEFINE_STATIC_ARRAY(uint32_t, factors,
192
                                    ARDUINOJSON_EXPAND6({
193
                                        0x3dcccccd,  // 1e-1f
194
                                        0x3c23d70a,  // 1e-2f
195
                                        0x38d1b717,  // 1e-4f
196
                                        0x322bcc77,  // 1e-8f
197
                                        0x24e69595,  // 1e-16f
198
                                        0x0a4fb11f   // 1e-32f
199
                                    }));
200
    return forge(ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, index));
201
  }
202

203
  static T negativeBinaryPowerOfTenPlusOne(int index) {
204
    ARDUINOJSON_DEFINE_STATIC_ARRAY(uint32_t, factors,
205
                                    ARDUINOJSON_EXPAND6({
206
                                        0x3f800000,  // 1e0f
207
                                        0x3dcccccd,  // 1e-1f
208
                                        0x3a83126f,  // 1e-3f
209
                                        0x33d6bf95,  // 1e-7f
210
                                        0x26901d7d,  // 1e-15f
211
                                        0x0c01ceb3   // 1e-31f
212
                                    }));
213
    return forge(ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, index));
214
  }
215

216
  static T forge(uint32_t bits) {
217
    return alias_cast<T>(bits);
218
  }
219

220
  static T nan() {
221
    return forge(0x7fc00000);
222
  }
223

224
  static T inf() {
225
    return forge(0x7f800000);
226
  }
227

228
  static T highest() {
229
    return forge(0x7f7fffff);
230
  }
231

232
  template <typename TOut>  // int32_t
233
  static T highest_for(
234
      typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
235
                             sizeof(TOut) == 4,
236
                         signed>::type* = 0) {
237
    return forge(0x4EFFFFFF);  // 2.14748352E9
238
  }
239

240
  template <typename TOut>  // uint32_t
241
  static T highest_for(
242
      typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
243
                             sizeof(TOut) == 4,
244
                         unsigned>::type* = 0) {
245
    return forge(0x4F7FFFFF);  // 4.29496704E9
246
  }
247

248
  template <typename TOut>  // int64_t
249
  static T highest_for(
250
      typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
251
                             sizeof(TOut) == 8,
252
                         signed>::type* = 0) {
253
    return forge(0x5EFFFFFF);  // 9.22337148709896192E18
254
  }
255

256
  template <typename TOut>  // uint64_t
257
  static T highest_for(
258
      typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
259
                             sizeof(TOut) == 8,
260
                         unsigned>::type* = 0) {
261
    return forge(0x5F7FFFFF);  // 1.844674297419792384E19
262
  }
263

264
  static T lowest() {
265
    return forge(0xFf7fffff);
266
  }
267
};
268
}  // namespace ARDUINOJSON_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc