FFstrbuf: improves double formatting precision handling

This commit is contained in:
李通洲
2025-08-19 16:03:04 +08:00
parent 8e282a3865
commit a7eecf6fc7
3 changed files with 41 additions and 10 deletions
+6 -7
View File
@@ -570,7 +570,7 @@ void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value)
strbuf->length += (uint32_t)(end - start);
}
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, uint8_t precision)
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision)
{
assert(precision <= 15); // yyjson_write_number supports up to 15 digits after the decimal point
@@ -579,12 +579,12 @@ void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, uint8_t precision)
yyjson_val val = {};
unsafe_yyjson_set_double(&val, value);
if (precision > 0) unsafe_yyjson_set_fp_to_fixed(&val, (int) precision);
if (precision >= 0) unsafe_yyjson_set_fp_to_fixed(&val, precision == 0 ? 1 : precision); // yyjson ignores precision == 0
// Write at most <precision> digits after the decimal point; doesn't append trailing zeros
char* end = yyjson_write_number(&val, start);
assert(end != NULL);
assert(end > start);
strbuf->length += (uint32_t)(end - start);
@@ -599,12 +599,11 @@ void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, uint8_t precision)
for (char* p = end - 1; *p != '.' && p > start; --p)
--precision;
if (precision > 0)
ffStrbufAppendNC(strbuf, precision, '0');
ffStrbufAppendNC(strbuf, (uint32_t) precision, '0');
}
else if (precision == 0 && end[-1] == '0' && end[-2] == '.')
else if (precision == 0 || (precision < 0 && end[-1] == '0'))
{
// yyjson always appends a decimal point if value is an integer
// Remove trailing zeros and the decimal point if precision is 0
// yyjson always appends ".0", so we need to remove it
strbuf->length -= 2;
strbuf->chars[strbuf->length] = '\0';
}
+3 -3
View File
@@ -105,9 +105,9 @@ int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint);
void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value);
void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value);
// Appends a double value to the string buffer with the specified precision.
// if `precision == 0`, let yyjson decide the precision
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, uint8_t precision);
// Appends a double value to the string buffer with the specified precision (0~15).
// if `precision < 0`, let yyjson decide the precision
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision);
FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate)
{
+32
View File
@@ -747,6 +747,10 @@ int main(void)
ffStrbufAppendDouble(&strbuf, 120.0, 0);
VERIFY(ffStrbufEqualS(&strbuf, "120"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 120.0, 1);
VERIFY(ffStrbufEqualS(&strbuf, "120.0"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 120.0, 5);
VERIFY(ffStrbufEqualS(&strbuf, "120.00000"));
@@ -757,6 +761,10 @@ int main(void)
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 120.123456789, 0);
VERIFY(ffStrbufEqualS(&strbuf, "120"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 120.123456789, -1);
VERIFY(ffStrbufEqualS(&strbuf, "120.123456789"));
ffStrbufClear(&strbuf);
@@ -767,6 +775,10 @@ int main(void)
ffStrbufAppendDouble(&strbuf, -120.0, 0);
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, -120.0, 1);
VERIFY(ffStrbufEqualS(&strbuf, "-120.0"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, -120.0, 5);
VERIFY(ffStrbufEqualS(&strbuf, "-120.00000"));
@@ -777,6 +789,10 @@ int main(void)
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, -120.123456789, 0);
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, -120.123456789, -1);
VERIFY(ffStrbufEqualS(&strbuf, "-120.123456789"));
ffStrbufClear(&strbuf);
@@ -791,6 +807,22 @@ int main(void)
ffStrbufAppendDouble(&strbuf, -1.2345e50, 1);
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 1.2345e50, 0);
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, -1.2345e50, 0);
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 1.2345e50, -1);
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, -1.2345e50, -1);
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
ffStrbufClear(&strbuf);
ffStrbufAppendDouble(&strbuf, 1.2345e20, 1);
VERIFY(ffStrbufEqualS(&strbuf, "123450000000000000000.0"));