-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathitoa.cpp
More file actions
137 lines (134 loc) · 2.85 KB
/
itoa.cpp
File metadata and controls
137 lines (134 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "itoa.h"
char *itoa(uint32_t value, char *result, uint32_t base)
{
static const char chars[] = "fedcba9876543210123456789abcdef";
// check that the base if valid
if (base < 2 || base > 16)
{
*result = '\0';
return result;
}
char *ptr = result;
char *ptr1 = result;
uint32_t tmp_value;
uint32_t count = 0;
do
{
tmp_value = value;
value /= base;
*ptr++ = chars[15 + (tmp_value - value * base)];
count++;
} while (value);
if (base != 10)
{
while (count++ < 8)
{
*ptr++ = '0';
};
}
*ptr-- = '\0';
while (ptr1 < ptr)
{
char tmp_char = *ptr;
*ptr-- = *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
char *itoa(int32_t value, char *result, uint32_t base)
{
static const char chars[] = "fedcba9876543210123456789abcdef";
// check that the base if valid
if (base < 2 || base > 16)
{
*result = '\0';
return result;
}
char *ptr = result;
char *ptr1 = result;
bool sign = value < 0;
value = value < 0 ? -value : value;
int32_t tmp_value;
do
{
tmp_value = value;
value /= base;
*ptr++ = chars[15 + (tmp_value - value * base)];
} while (value);
// Apply negative sign
if (sign)
*ptr++ = '-';
*ptr-- = '\0';
while (ptr1 < ptr)
{
char tmp_char = *ptr;
*ptr-- = *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
char *fptoa(int32_t value, char *result, uint32_t BITSF, uint32_t precision)
{
static const char chars[] = "0123456789----------";
// make value absolute
int32_t tmp_value = static_cast<uint32_t>(value < 0 ? -value : value);
int32_t intPart = tmp_value >> BITSF;
int32_t fractPart = (tmp_value & ((1 << BITSF) - 1));
// convert integer part
char *ptr = result;
do
{
tmp_value = intPart;
intPart /= 10;
*ptr++ = chars[tmp_value - intPart * 10];
} while (intPart);
// apply negative sign
if (value < 0)
*ptr++ = '-';
// store end of int string for appending fraction
char *intEnd = ptr--;
// swap int string back-to-front
char *ptr1 = result;
while (ptr1 < ptr)
{
char tmp_char = *ptr;
*ptr-- = *ptr1;
*ptr1++ = tmp_char;
}
// add decimal point
*intEnd++ = '.';
// convert fractional part with rounding
if (precision > 0)
{
const uint32_t BITSQ_MASK = ~((1 << BITSF) - 1);
const int32_t HALF = int32_t(1) << (BITSF - 1);
int32_t multiplier = 1;
for (uint32_t i = 0; i < precision; i++)
{
multiplier *= 10;
}
fractPart *= multiplier;
fractPart += (value < 0) ? (-HALF) : HALF; // -0.5 / +0.5
fractPart &= BITSQ_MASK; // trunc
for (uint32_t i = 0; i < precision; i++)
{
multiplier /= 10;
auto number = (fractPart / multiplier) & BITSQ_MASK;
*intEnd++ = chars[number >> BITSF];
fractPart -= number * multiplier;
}
}
// convert fractional part w/o rounding
else
{
do
{
fractPart *= 10;
*intEnd++ = chars[fractPart >> BITSF];
fractPart &= ((1 << BITSF) - 1);
} while (fractPart);
}
// null-terminate
*intEnd = '\0';
return result;
}