dconv 2.0
C++14 library for printing and parsing floating point numbers
Loading...
Searching...
No Matches
format.hpp
Go to the documentation of this file.
1
25#ifndef __DCONV_FORMAT_HPP__
26#define __DCONV_FORMAT_HPP__
27
28// dconv.
29#include <dconv/digits.hpp>
30
31// C.
32#include <cstring>
33#include <cassert>
34#include <cstdint>
35
36namespace dconv
37{
38 namespace details
39 {
46 inline char* writeExponent (char* buffer, int k) noexcept
47 {
48 *buffer = '-';
49 buffer += (k < 0);
50 k = (k < 0) ? -k : k;
51 if (k >= 100)
52 {
53 *buffer++ = static_cast<char> ('0' + k / 100);
54 __builtin_memcpy (buffer, &digitPairs[(k % 100) * 2], 2);
55 buffer += 2;
56 }
57 else if (k >= 10)
58 {
59 __builtin_memcpy (buffer, &digitPairs[k * 2], 2);
60 buffer += 2;
61 }
62 else
63 {
64 *buffer++ = static_cast<char> ('0' + k);
65 }
66 return buffer;
67 }
68
76 inline char* prettify (char* buffer, int length, int k) noexcept
77 {
78 assert (length > 0);
79 const int kk = length + k;
80
81 if ((length <= kk) && (kk <= 21))
82 {
83 memset (buffer + length, '0', kk - length);
84 buffer[kk] = '.';
85 buffer[kk + 1] = '0';
86 return &buffer[kk + 2];
87 }
88 else if ((0 < kk) && (kk <= 21))
89 {
90 if ((length - kk <= 16) && (kk <= 7))
91 {
92 char tmp[16];
93 memcpy (tmp, &buffer[kk], 16);
94 memcpy (&buffer[kk + 1], tmp, 16);
95 }
96 else
97 {
98 memmove (&buffer[kk + 1], &buffer[kk], length - kk);
99 }
100 buffer[kk] = '.';
101 return &buffer[length + 1];
102 }
103 else if ((-6 < kk) && (kk <= 0))
104 {
105 int offset = 2 - kk;
106 memmove (&buffer[offset], &buffer[0], length);
107 buffer[0] = '0';
108 buffer[1] = '.';
109 memset (&buffer[2], '0', offset - 2);
110 return &buffer[length + offset];
111 }
112 else if (length == 1)
113 {
114 buffer[1] = 'e';
115 return writeExponent (&buffer[2], kk - 1);
116 }
117 else
118 {
119 if (length - 1 <= 16)
120 {
121 char tmp[16];
122 memcpy (tmp, &buffer[1], 16);
123 memcpy (&buffer[2], tmp, 16);
124 }
125 else
126 {
127 memmove (&buffer[2], &buffer[1], length - 1);
128 }
129 buffer[1] = '.';
130 buffer[length + 1] = 'e';
131 return writeExponent (&buffer[length + 2], kk - 1);
132 }
133 }
134
143 inline char* format (char* buffer, uint64_t digits, int length, int k) noexcept
144 {
145 const int kk = length + k;
146
147 if ((kk > 21) || (kk <= -6))
148 {
149 length -= writeDigits (buffer + 1, digits, length);
150 buffer[0] = buffer[1];
151 buffer[1] = '.';
152 const int position = (length > 1) ? length + 1 : 1;
153 buffer[position] = 'e';
154 return writeExponent (&buffer[position + 1], kk - 1);
155 }
156
157 if (length <= kk)
158 {
159 writeDigits (buffer, digits, length);
160 for (int i = length; i < kk; ++i)
161 {
162 buffer[i] = '0';
163 }
164 buffer[kk] = '.';
165 buffer[kk + 1] = '0';
166 return &buffer[kk + 2];
167 }
168 else if (0 < kk)
169 {
170 length -= writeDigits (buffer + 1, digits, length);
171 for (int i = 0; i < kk; ++i)
172 {
173 buffer[i] = buffer[i + 1];
174 }
175 buffer[kk] = '.';
176 return &buffer[length + 1];
177 }
178 else
179 {
180 const int offset = 2 - kk;
181 buffer[0] = '0';
182 buffer[1] = '.';
183 for (int i = 2; i < offset; ++i)
184 {
185 buffer[i] = '0';
186 }
187 length -= writeDigits (buffer + offset, digits, length);
188 return &buffer[length + offset];
189 }
190 }
191 }
192}
193
194#endif
char * prettify(char *buffer, int length, int k) noexcept
lay out decimal digits as a fixed or scientific number.
Definition format.hpp:76
char * format(char *buffer, uint64_t digits, int length, int k) noexcept
write a decimal significand with the same layout as prettify.
Definition format.hpp:143
char * writeExponent(char *buffer, int k) noexcept
write a decimal exponent.
Definition format.hpp:46
int writeDigits(char *buffer, uint64_t digits, int length) noexcept
write the digits of a decimal significand.
Definition digits.hpp:108
constexpr char digitPairs[]
two digits decimal representations of 0 to 99.
Definition digits.hpp:39
Definition atod.hpp:47