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

bblanchon / ArduinoJson / 10700044544

04 Sep 2024 10:40AM CUT coverage: 99.301%. First build
10700044544

push

github

bblanchon
Approx

3975 of 4003 relevant lines covered (99.3%)

10563.62 hits per line

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

95.45
/src/ArduinoJson/Numbers/FloatTraits.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2024, 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/pgmspace_generic.hpp>
14
#include <ArduinoJson/Polyfills/preprocessor.hpp>
15
#include <ArduinoJson/Polyfills/type_traits.hpp>
16

17
ARDUINOJSON_BEGIN_PRIVATE_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
  static pgm_ptr<T> positiveBinaryPowersOfTen() {
118✔
33
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
×
34
        uint64_t, factors,
35
        {
36
            0x4024000000000000,  // 1e1
37
            0x4059000000000000,  // 1e2
38
            0x40C3880000000000,  // 1e4
39
            0x4197D78400000000,  // 1e8
40
            0x4341C37937E08000,  // 1e16
41
            0x4693B8B5B5056E17,  // 1e32
42
            0x4D384F03E93FF9F5,  // 1e64
43
            0x5A827748F9301D32,  // 1e128
44
            0x75154FDD7F73BF3C,  // 1e256
45
        });
46
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
118✔
47
  }
48

49
  static pgm_ptr<T> negativeBinaryPowersOfTen() {
116✔
50
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
×
51
        uint64_t, factors,
52
        {
53
            0x3FB999999999999A,  // 1e-1
54
            0x3F847AE147AE147B,  // 1e-2
55
            0x3F1A36E2EB1C432D,  // 1e-4
56
            0x3E45798EE2308C3A,  // 1e-8
57
            0x3C9CD2B297D889BC,  // 1e-16
58
            0x3949F623D5A8A733,  // 1e-32
59
            0x32A50FFD44F4A73D,  // 1e-64
60
            0x255BBA08CF8C979D,  // 1e-128
61
            0x0AC8062864AC6F43   // 1e-256
62
        });
63
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
116✔
64
  }
65

66
  static T nan() {
6✔
67
    return forge(0x7ff8000000000000);
6✔
68
  }
69

70
  static T inf() {
15✔
71
    return forge(0x7ff0000000000000);
15✔
72
  }
73

74
  static T highest() {
75
    return forge(0x7FEFFFFFFFFFFFFF);
76
  }
77

78
  template <typename TOut>  // int64_t
79
  static T highest_for(
5✔
80
      enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
81
                      sizeof(TOut) == 8,
82
                  signed>* = 0) {
83
    return forge(0x43DFFFFFFFFFFFFF);  //  9.2233720368547748e+18
5✔
84
  }
85

86
  template <typename TOut>  // uint64_t
87
  static T highest_for(
3✔
88
      enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
89
                      sizeof(TOut) == 8,
90
                  unsigned>* = 0) {
91
    return forge(0x43EFFFFFFFFFFFFF);  //  1.8446744073709549568e+19
3✔
92
  }
93

94
  static T lowest() {
95
    return forge(0xFFEFFFFFFFFFFFFF);
96
  }
97

98
  // constructs a double floating point values from its binary representation
99
  // we use this function to workaround platforms with single precision literals
100
  // (for example, when -fsingle-precision-constant is passed to GCC)
101
  static T forge(uint64_t bits) {
29✔
102
    return alias_cast<T>(bits);
29✔
103
  }
104
};
105

106
template <typename T>
107
struct FloatTraits<T, 4 /*32bits*/> {
108
  typedef uint32_t mantissa_type;
109
  static const short mantissa_bits = 23;
110
  static const mantissa_type mantissa_max =
111
      (mantissa_type(1) << mantissa_bits) - 1;
112

113
  typedef int8_t exponent_type;
114
  static const exponent_type exponent_max = 38;
115

116
  static pgm_ptr<T> positiveBinaryPowersOfTen() {
19✔
117
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
1✔
118
                                     {
119
                                         0x41200000,  // 1e1f
120
                                         0x42c80000,  // 1e2f
121
                                         0x461c4000,  // 1e4f
122
                                         0x4cbebc20,  // 1e8f
123
                                         0x5a0e1bca,  // 1e16f
124
                                         0x749dc5ae   // 1e32f
125
                                     });
126
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
19✔
127
  }
128

129
  static pgm_ptr<T> negativeBinaryPowersOfTen() {
83✔
130
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
1✔
131
                                     {
132
                                         0x3dcccccd,  // 1e-1f
133
                                         0x3c23d70a,  // 1e-2f
134
                                         0x38d1b717,  // 1e-4f
135
                                         0x322bcc77,  // 1e-8f
136
                                         0x24e69595,  // 1e-16f
137
                                         0x0a4fb11f   // 1e-32f
138
                                     });
139
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
83✔
140
  }
141

142
  static T forge(uint32_t bits) {
39✔
143
    return alias_cast<T>(bits);
39✔
144
  }
145

146
  static T nan() {
147
    return forge(0x7fc00000);
148
  }
149

150
  static T inf() {
2✔
151
    return forge(0x7f800000);
2✔
152
  }
153

154
  static T highest() {
155
    return forge(0x7f7fffff);
156
  }
157

158
  template <typename TOut>  // int32_t
159
  static T highest_for(
5✔
160
      enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
161
                      sizeof(TOut) == 4,
162
                  signed>* = 0) {
163
    return forge(0x4EFFFFFF);  // 2.14748352E9
5✔
164
  }
165

166
  template <typename TOut>  // uint32_t
167
  static T highest_for(
4✔
168
      enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
169
                      sizeof(TOut) == 4,
170
                  unsigned>* = 0) {
171
    return forge(0x4F7FFFFF);  // 4.29496704E9
4✔
172
  }
173

174
  template <typename TOut>  // int64_t
175
  static T highest_for(
25✔
176
      enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
177
                      sizeof(TOut) == 8,
178
                  signed>* = 0) {
179
    return forge(0x5EFFFFFF);  // 9.22337148709896192E18
25✔
180
  }
181

182
  template <typename TOut>  // uint64_t
183
  static T highest_for(
3✔
184
      enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
185
                      sizeof(TOut) == 8,
186
                  unsigned>* = 0) {
187
    return forge(0x5F7FFFFF);  // 1.844674297419792384E19
3✔
188
  }
189

190
  static T lowest() {
191
    return forge(0xFf7fffff);
192
  }
193
};
194

195
template <typename TFloat, typename TExponent>
196
inline TFloat make_float(TFloat m, TExponent e) {
133✔
197
  using traits = FloatTraits<TFloat>;
198

199
  auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen()
133✔
200
                           : traits::negativeBinaryPowersOfTen();
96✔
201
  if (e <= 0)
133✔
202
    e = TExponent(-e);
96✔
203

204
  for (uint8_t index = 0; e != 0; index++) {
612✔
205
    if (e & 1)
479✔
206
      m *= powersOfTen[index];
221✔
207
    e >>= 1;
479✔
208
  }
209
  return m;
133✔
210
}
211

212
ARDUINOJSON_END_PRIVATE_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