Convert to output to std::string

This commit is contained in:
Eric Fischer
2017-08-29 14:26:20 -07:00
parent 5f09ccae88
commit 3840176d5c
+41 -41
View File
@@ -203,7 +203,7 @@ inline DiyFp GetCachedPower(int e, int* K) {
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
} }
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { inline void GrisuRound(std::string &buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
while (rest < wp_w && delta - rest >= ten_kappa && while (rest < wp_w && delta - rest >= ten_kappa &&
(rest + ten_kappa < wp_w || /// closer (rest + ten_kappa < wp_w || /// closer
wp_w - rest > rest + ten_kappa - wp_w)) { wp_w - rest > rest + ten_kappa - wp_w)) {
@@ -226,7 +226,7 @@ inline unsigned CountDecimalDigit32(uint32_t n) {
return 10; return 10;
} }
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, std::string &buffer, int* len, int* K) {
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
const DiyFp wp_w = Mp - W; const DiyFp wp_w = Mp - W;
@@ -257,8 +257,10 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
d = 0; d = 0;
#endif #endif
} }
if (d || *len) if (d || *len) {
buffer[(*len)++] = '0' + static_cast<char>(d); buffer.push_back('0' + static_cast<char>(d));
(*len)++;
}
kappa--; kappa--;
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2; uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
if (tmp <= delta) { if (tmp <= delta) {
@@ -273,8 +275,10 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
p2 *= 10; p2 *= 10;
delta *= 10; delta *= 10;
char d = static_cast<char>(p2 >> -one.e); char d = static_cast<char>(p2 >> -one.e);
if (d || *len) if (d || *len) {
buffer[(*len)++] = '0' + d; buffer.push_back('0' + d);
(*len)++;
}
p2 &= one.f - 1; p2 &= one.f - 1;
kappa--; kappa--;
if (p2 < delta) { if (p2 < delta) {
@@ -285,7 +289,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
} }
} }
inline void Grisu2(double value, char* buffer, int* length, int* K) { inline void Grisu2(double value, std::string &buffer, int* length, int* K) {
const DiyFp v(value); const DiyFp v(value);
DiyFp w_m, w_p; DiyFp w_m, w_p;
v.NormalizedBoundaries(&w_m, &w_p); v.NormalizedBoundaries(&w_m, &w_p);
@@ -315,91 +319,87 @@ inline const char* GetDigitsLut() {
return cDigitsLut; return cDigitsLut;
} }
inline void WriteExponent(int K, char* buffer) { inline void WriteExponent(int K, std::string &buffer) {
if (K < 0) { if (K < 0) {
*buffer++ = '-'; buffer.push_back('-');
K = -K; K = -K;
} }
if (K >= 100) { if (K >= 100) {
*buffer++ = '0' + static_cast<char>(K / 100); buffer.push_back('0' + static_cast<char>(K / 100));
K %= 100; K %= 100;
const char* d = GetDigitsLut() + K * 2; const char* d = GetDigitsLut() + K * 2;
*buffer++ = d[0]; buffer.push_back(d[0]);
*buffer++ = d[1]; buffer.push_back(d[1]);
} }
else if (K >= 10) { else if (K >= 10) {
const char* d = GetDigitsLut() + K * 2; const char* d = GetDigitsLut() + K * 2;
*buffer++ = d[0]; buffer.push_back(d[0]);
*buffer++ = d[1]; buffer.push_back(d[1]);
} }
else else
*buffer++ = '0' + static_cast<char>(K); buffer.push_back('0' + static_cast<char>(K));
*buffer = '\0';
} }
inline void Prettify(char* buffer, int length, int k) { inline void Prettify(std::string &buffer, int length, int k) {
const int kk = length + k; // 10^(kk-1) <= v < 10^kk const int kk = length + k; // 10^(kk-1) <= v < 10^kk
if (length <= kk && kk <= 21) { if (length <= kk && kk <= 21) {
// 1234e7 -> 12340000000 // 1234e7 -> 12340000000
for (int i = length; i < kk; i++) for (int i = length; i < kk; i++)
buffer[i] = '0'; buffer.push_back('0');
buffer[kk] = '.';
buffer[kk + 1] = '0';
buffer[kk + 2] = '\0';
} }
else if (0 < kk && kk <= 21) { else if (0 < kk && kk <= 21) {
// 1234e-2 -> 12.34 // 1234e-2 -> 12.34
memmove(&buffer[kk + 1], &buffer[kk], length - kk); buffer.insert(buffer.begin() + kk, '.');
buffer[kk] = '.';
buffer[length + 1] = '\0';
} }
else if (-6 < kk && kk <= 0) { else if (-6 < kk && kk <= 0) {
// 1234e-6 -> 0.001234 // 1234e-6 -> 0.001234
const int offset = 2 - kk; const int offset = 2 - kk;
memmove(&buffer[offset], &buffer[0], length); memmove(&buffer[offset], &buffer[0], length);
buffer[0] = '0'; buffer.insert(buffer.begin(), '0');
buffer[1] = '.'; buffer.insert(buffer.begin() + 1, '0');
for (int i = 2; i < offset; i++) for (int i = 2; i < offset; i++)
buffer[i] = '0'; buffer.insert(buffer.begin() + 2, '0');
buffer[length + offset] = '\0';
} }
else if (length == 1) { else if (length == 1) {
// 1e30 // 1e30
buffer[1] = 'e'; buffer.push_back('e');
WriteExponent(kk - 1, &buffer[2]); WriteExponent(kk - 1, buffer);
} }
else { else {
// 1234e30 -> 1.234e33 // 1234e30 -> 1.234e33
memmove(&buffer[2], &buffer[1], length - 1); buffer.insert(buffer.begin() + 1, '.');
buffer[1] = '.'; buffer.push_back('e');
buffer[length + 1] = 'e'; WriteExponent(kk - 1, buffer);
WriteExponent(kk - 1, &buffer[0 + length + 2]);
} }
} }
inline void dtoa_milo(double value, char* buffer) { inline std::string dtoa_milo(double value) {
std::string buffer;
// Not handling NaN and inf // Not handling NaN and inf
assert(!isnan(value)); assert(!isnan(value));
assert(!isinf(value)); assert(!isinf(value));
if (value == 0) { if (value == 0) {
buffer[0] = '0'; buffer = "0";
buffer[1] = '.';
buffer[2] = '0';
buffer[3] = '\0';
} }
else { else {
bool minus = false;
if (value < 0) { if (value < 0) {
*buffer++ = '-'; minus = true;
value = -value; value = -value;
} }
int length, K; int length, K;
Grisu2(value, buffer, &length, &K); Grisu2(value, buffer, &length, &K);
Prettify(buffer, length, K); Prettify(buffer, length, K);
if (minus) {
buffer.insert(buffer.begin(), '-');
}
} }
return buffer;
} }
} }