Skip to content

Commit 950f716

Browse files
authored
1 parent 0f8bd8d commit 950f716

File tree

2 files changed

+77
-16
lines changed

2 files changed

+77
-16
lines changed

src/string.cpp

+24-15
Original file line numberDiff line numberDiff line change
@@ -887,25 +887,34 @@ namespace bx
887887
const char* dot = strFind(str, INT32_MAX, '.');
888888
if (NULL != dot)
889889
{
890-
const int32_t prec = INT32_MAX == _param.prec ? len-(dot+1-str) : _param.prec;
891-
892-
const int32_t precLen = int32_t(
893-
dot
894-
+ min(prec + _param.spec, 1)
895-
+ prec
896-
- str
897-
);
898-
if (precLen > len)
890+
const int32_t prec = INT32_MAX == _param.prec ? 6 : _param.prec;
891+
const char* strEnd = str + len;
892+
const char* exponent = strFind(str, INT32_MAX, 'e');
893+
const char* fracEnd = NULL != exponent ? exponent : strEnd;
894+
char* fracBegin = &str[dot - str + min(prec + _param.spec, 1)];
895+
const int32_t curPrec = int32_t(fracEnd - fracBegin);
896+
897+
// Move exponent to its final location after trimming or adding extra 0s.
898+
if (fracEnd != strEnd)
899899
{
900-
for (int32_t ii = len; ii < precLen; ++ii)
900+
const int32_t exponentLen = int32_t(strEnd - fracEnd);
901+
char* finalExponentPtr = &fracBegin[prec];
902+
memMove(finalExponentPtr, fracEnd, exponentLen); // NOTE: Use memMove because there may be overlap.
903+
finalExponentPtr[exponentLen] = '\0';
904+
len = int32_t(&finalExponentPtr[exponentLen] - str);
905+
}
906+
else
907+
{
908+
len = (int32_t)(fracBegin + prec - str);
909+
}
910+
911+
if (curPrec < prec)
912+
{
913+
for (int32_t ii = curPrec; ii < prec; ++ii)
901914
{
902-
str[ii] = '0';
915+
fracBegin[ii] = '0';
903916
}
904-
905-
str[precLen] = '\0';
906917
}
907-
908-
len = precLen;
909918
}
910919

911920
return write(_writer, str, len, _param, _err);

tests/vsnprintf_test.cpp

+53-1
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,61 @@ TEST_CASE("vsnprintf f")
7474
REQUIRE(test("-001.500", "%+08.3f", -1.5) );
7575
REQUIRE(test("0.0039", "%.4f", 0.00390625) );
7676

77-
REQUIRE(test("0.00390625", "%f", 0.00390625) );
77+
REQUIRE(test("0.003906", "%f", 0.00390625) );
7878
REQUIRE(test("-1.234567e-9", "%f", -1.234567e-9) );
7979

80+
REQUIRE(test("-1e-9", "%.0f", -1.234567e-9) );
81+
REQUIRE(test("-1.2e-9", "%.1f", -1.234567e-9) );
82+
REQUIRE(test("-1.23e-9", "%.2f", -1.234567e-9) );
83+
REQUIRE(test("-1.234e-9", "%.3f", -1.234567e-9) );
84+
REQUIRE(test("-1.2345e-9", "%.4f", -1.234567e-9) );
85+
REQUIRE(test("-1.23456e-9", "%.5f", -1.234567e-9) );
86+
REQUIRE(test("-1.234567e-9", "%.6f", -1.234567e-9) );
87+
REQUIRE(test("-1.2345670e-9", "%.7f", -1.234567e-9) );
88+
REQUIRE(test("-1.23456700e-9", "%.8f", -1.234567e-9) );
89+
REQUIRE(test("-1.234567000e-9", "%.9f", -1.234567e-9) );
90+
REQUIRE(test("-1.2345670000e-9", "%.10f", -1.234567e-9) );
91+
92+
REQUIRE(test("3.141592", "%f", 3.1415926535897932) );
93+
REQUIRE(test("3", "%.0f", 3.1415926535897932) );
94+
REQUIRE(test("3.1", "%.1f", 3.1415926535897932) );
95+
REQUIRE(test("3.14", "%.2f", 3.1415926535897932) );
96+
REQUIRE(test("3.141", "%.3f", 3.1415926535897932) );
97+
REQUIRE(test("3.1415", "%.4f", 3.1415926535897932) );
98+
REQUIRE(test("3.14159", "%.5f", 3.1415926535897932) );
99+
REQUIRE(test("3.141592", "%.6f", 3.1415926535897932) );
100+
REQUIRE(test("3.1415926", "%.7f", 3.1415926535897932) );
101+
REQUIRE(test("3.14159265", "%.8f", 3.1415926535897932) );
102+
REQUIRE(test("3.141592653", "%.9f", 3.1415926535897932) );
103+
REQUIRE(test("3.1415926535", "%.10f", 3.1415926535897932) );
104+
REQUIRE(test("3.14159265358", "%.11f", 3.1415926535897932) );
105+
REQUIRE(test("3.141592653589", "%.12f", 3.1415926535897932) );
106+
REQUIRE(test("3.1415926535897", "%.13f", 3.1415926535897932) );
107+
REQUIRE(test("3.14159265358979", "%.14f", 3.1415926535897932) );
108+
REQUIRE(test("3.141592653589793", "%.15f", 3.1415926535897932) );
109+
REQUIRE(test("3.1415926535897930", "%.16f", 3.1415926535897932) );
110+
111+
REQUIRE(test("-3.141592e-9", "%f", -3.1415926535897932e-9) );
112+
REQUIRE(test("-3e-9", "%.0f", -3.1415926535897932e-9) );
113+
REQUIRE(test("-3.1e-9", "%.1f", -3.1415926535897932e-9) );
114+
REQUIRE(test("-3.14e-9", "%.2f", -3.1415926535897932e-9) );
115+
REQUIRE(test("-3.141e-9", "%.3f", -3.1415926535897932e-9) );
116+
REQUIRE(test("-3.1415e-9", "%.4f", -3.1415926535897932e-9) );
117+
REQUIRE(test("-3.14159e-9", "%.5f", -3.1415926535897932e-9) );
118+
REQUIRE(test("-3.141592e-9", "%.6f", -3.1415926535897932e-9) );
119+
REQUIRE(test("-3.1415926e-9", "%.7f", -3.1415926535897932e-9) );
120+
REQUIRE(test("-3.14159265e-9", "%.8f", -3.1415926535897932e-9) );
121+
REQUIRE(test("-3.141592653e-9", "%.9f", -3.1415926535897932e-9) );
122+
REQUIRE(test("-3.1415926535e-9", "%.10f", -3.1415926535897932e-9) );
123+
REQUIRE(test("-3.14159265358e-9", "%.11f", -3.1415926535897932e-9) );
124+
REQUIRE(test("-3.141592653589e-9", "%.12f", -3.1415926535897932e-9) );
125+
REQUIRE(test("-3.1415926535897e-9", "%.13f", -3.1415926535897932e-9) );
126+
REQUIRE(test("-3.14159265358979e-9", "%.14f", -3.1415926535897932e-9) );
127+
REQUIRE(test("-3.141592653589793e-9", "%.15f", -3.1415926535897932e-9) );
128+
REQUIRE(test("-3.1415926535897930e-9", "%.16f", -3.1415926535897932e-9) );
129+
130+
REQUIRE(test("1e-12", "%f", 1e-12));
131+
80132
REQUIRE(test("0.00390625", "%.8f", 0.00390625) );
81133
REQUIRE(test("-0.00390625", "%.8f", -0.00390625) );
82134
REQUIRE(test("1.50000000000000000", "%.17f", 1.5) );

0 commit comments

Comments
 (0)