Line data Source code
1 : #include <stdint.h>
2 : #include <stdbool.h>
3 : #include "xtoa.hpp"
4 :
5 : namespace FreeRTOS_Cpp {
6 :
7 11 : void xtoa::app_itoa(int32_t val, char *str, uint32_t len)
8 : {
9 11 : if (len < 2U)
10 0 : return; // Buffer too small for even a single digit + null
11 :
12 : uint32_t uval;
13 11 : uint32_t pos = 0;
14 :
15 : // 1. Handle Negative Sign
16 11 : if (val < 0)
17 : {
18 3 : str[pos++] = '-';
19 3 : uval = static_cast<uint32_t>(-val);
20 : }
21 : else
22 : {
23 8 : uval = static_cast<uint32_t>(val);
24 : }
25 :
26 : // 2. Handle '0' explicitly
27 11 : if (uval == 0U)
28 : {
29 3 : if (pos < (len - 1U))
30 : {
31 3 : str[pos++] = '0';
32 3 : str[pos] = '\0';
33 : }
34 3 : return;
35 : }
36 :
37 : // 3. Calculate digits for the absolute value
38 8 : uint32_t digits = 0;
39 8 : uint32_t temp = uval;
40 46 : while (temp > 0U)
41 : {
42 38 : digits++;
43 38 : temp /= 10U;
44 : }
45 :
46 : // 4. Check if total string fits: (sign? + digits + null)
47 8 : if ((pos + digits) < len)
48 : {
49 8 : str[pos + digits] = '\0';
50 46 : for (uint32_t i = digits; i > 0U; i--)
51 : {
52 38 : str[pos + i - 1U] = static_cast<char>((uval % 10U) + '0');
53 38 : uval /= 10U;
54 : }
55 : }
56 : }
57 :
58 2 : void xtoa::app_ftoa(float val, char *str, uint32_t len) {
59 2 : if (len < 6U) return; // Need space for "0.00\0"
60 :
61 : // 1. Handle Negative Floats
62 2 : if (val < 0.0f)
63 : {
64 0 : str[0] = '-';
65 : // Recursively call with positive value, shifting buffer by 1
66 0 : app_ftoa(-val, &str[1], len - 1U);
67 0 : return;
68 : }
69 :
70 : // 2. Extract Parts
71 2 : int32_t integer_part = static_cast<int32_t>(val);
72 : // Rounding to 2 decimal places: multiply by 100 and add 0.5 for rounding
73 2 : uint32_t fractional_part = static_cast<uint32_t>((val - static_cast<float>(integer_part)) * 100.0f + 0.5f);
74 :
75 : // Handle case where fractional rounding rolls over (e.g., 3.999 -> 4.00)
76 2 : if (fractional_part >= 100U) {
77 0 : integer_part++;
78 0 : fractional_part = 0U;
79 : }
80 :
81 : // 3. Convert Integer Part
82 2 : app_itoa(integer_part, str, len);
83 :
84 : // 4. Find end of integer part
85 2 : uint32_t i = 0;
86 5 : while ((i < (len - 1U)) && (str[i] != '\0')) { i++; }
87 :
88 : // 5. Append Decimal and Fraction
89 2 : if (i < (len - 4U)) {
90 2 : str[i++] = '.';
91 2 : str[i++] = static_cast<char>((fractional_part / 10U) + '0');
92 2 : str[i++] = static_cast<char>((fractional_part % 10U) + '0');
93 2 : str[i] = '\0';
94 : }
95 : }
96 : }
|