Coverage Report

Created: 2026-10-28 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/arduinojson/src/ArduinoJson/Numbers/FloatParts.hpp
Line
Count
Source
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2026, Benoit BLANCHON
3
// MIT License
4
5
#pragma once
6
7
#include <ArduinoJson/Configuration.hpp>
8
#include <ArduinoJson/Numbers/FloatTraits.hpp>
9
#include <ArduinoJson/Numbers/JsonFloat.hpp>
10
#include <ArduinoJson/Polyfills/math.hpp>
11
12
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
13
14
struct FloatParts {
15
  uint32_t integral;
16
  uint32_t decimal;
17
  int16_t exponent;
18
  int8_t decimalPlaces;
19
};
20
21
template <typename TFloat>
22
6.36k
inline int16_t normalize(TFloat& value) {
23
6.36k
  using traits = FloatTraits<TFloat>;
24
6.36k
  int16_t powersOf10 = 0;
25
26
6.36k
  int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
27
6.36k
  int bit = 1 << index;
28
29
6.36k
  if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
30
15.6k
    for (; index >= 0; index--) {
31
14.0k
      if (value >= traits::positiveBinaryPowersOfTen()[uint8_t(index)]) {
32
6.04k
        value *= traits::negativeBinaryPowersOfTen()[uint8_t(index)];
33
6.04k
        powersOf10 = int16_t(powersOf10 + bit);
34
6.04k
      }
35
14.0k
      bit >>= 1;
36
14.0k
    }
37
1.56k
  }
38
39
6.36k
  if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
40
4.17k
    for (; index >= 0; index--) {
41
3.75k
      if (value < traits::negativeBinaryPowersOfTen()[uint8_t(index)] * 10) {
42
877
        value *= traits::positiveBinaryPowersOfTen()[uint8_t(index)];
43
877
        powersOf10 = int16_t(powersOf10 - bit);
44
877
      }
45
3.75k
      bit >>= 1;
46
3.75k
    }
47
417
  }
48
49
6.36k
  return powersOf10;
50
6.36k
}
51
52
48.5k
constexpr uint32_t pow10(int exponent) {
53
48.5k
  return (exponent == 0) ? 1 : 10 * pow10(exponent - 1);
54
48.5k
}
55
56
6.36k
inline FloatParts decomposeFloat(JsonFloat value, int8_t decimalPlaces) {
57
6.36k
  uint32_t maxDecimalPart = pow10(decimalPlaces);
58
59
6.36k
  int16_t exponent = normalize(value);
60
61
6.36k
  uint32_t integral = uint32_t(value);
62
  // reduce number of decimal places by the number of integral places
63
8.61k
  for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
64
2.25k
    maxDecimalPart /= 10;
65
2.25k
    decimalPlaces--;
66
2.25k
  }
67
68
6.36k
  JsonFloat remainder =
69
6.36k
      (value - JsonFloat(integral)) * JsonFloat(maxDecimalPart);
70
71
6.36k
  uint32_t decimal = uint32_t(remainder);
72
6.36k
  remainder = remainder - JsonFloat(decimal);
73
74
  // rounding:
75
  // increment by 1 if remainder >= 0.5
76
6.36k
  decimal += uint32_t(remainder * 2);
77
6.36k
  if (decimal >= maxDecimalPart) {
78
665
    decimal = 0;
79
665
    integral++;
80
665
    if (exponent && integral >= 10) {
81
237
      exponent++;
82
237
      integral = 1;
83
237
    }
84
665
  }
85
86
  // remove trailing zeros
87
44.2k
  while (decimal % 10 == 0 && decimalPlaces > 0) {
88
37.8k
    decimal /= 10;
89
37.8k
    decimalPlaces--;
90
37.8k
  }
91
92
6.36k
  return {integral, decimal, exponent, decimalPlaces};
93
6.36k
}
94
95
ARDUINOJSON_END_PRIVATE_NAMESPACE