Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/CLR/CorLib/corlib_native_System_Number.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,10 +718,11 @@ int Library_corlib_native_System_Number::Format_F(

ret = DoPrintfOnDataType(buffer, formatStr, value);

bool isNegative = (buffer[0] == '-');

// this extra processing is only required for integer types
if (isIntegerDataType && ret > 0)
{
bool isNegative = (buffer[0] == '-');
int offsetBecauseOfNegativeSign = (isNegative ? 1 : 0);

int dotIndex = GetDotIndex(buffer, ret);
Expand Down Expand Up @@ -756,6 +757,13 @@ int Library_corlib_native_System_Number::Format_F(
ret = ReplaceNegativeSign(buffer, ret, negativeSign);
ret = ReplaceDecimalSeparator(buffer, ret, decimalSeparator);
}
else if (isNegative && ret == 2 && buffer[1] == '0')
{
// handle negative zero: if the value was negative but rounds to 0, remove the minus sign
// remove the negative sign
memmove(buffer, &buffer[1], ret);
ret--;
}

return ret;
}
Expand Down
59 changes: 36 additions & 23 deletions src/CLR/Helpers/nanoprintf/nanoprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,34 +418,39 @@ static char *format_float(double number, flt_width_t ndigits, flt_width_t width,
{
p -= (i - FLOAT_DIGITS);
}
if (!(fflags & FF_NRND) && *p >= '5')
// Use the rounding digit at 'pend' (the extra generated digit)
if (!(fflags & FF_NRND) && *pend >= '5')
{
for (;;)
char *start = buf +2; // first generated digit position
char *q = pend -1; // last significant digit

// Set rounding digit to zero; it will be dropped later
*pend = '0';

// Propagate carry leftwards
while (q >= start && *q == '9')
{
*q = '0';
--q;
}

if (q < start)
{
if (i == 0)
// Rollover past the most significant digit, e.g.,9.999 ->10.000
*start = '1';
++decpt;
// In fixed 'f' mode, this increases displayed digits
if ((fflags & (FF_FCVT | FF_GCVT)) == FF_FCVT)
{
// The rounding has rippled all the way through to
// the first digit. i.e. 9.999..9 -> 10.0
// Just replace the first 0 with a 1 and shift the DP.
*p = '1';
++decpt;
// This increases the displayed digits for 'f' only.
if ((fflags & (FF_FCVT|FF_GCVT)) == FF_FCVT)
{
++ndigits;
++pend;
}
break;
}
// Previous digit was a rollover
*p-- = '0';
// Increment next digit and break out unless there is a rollover.
if (*p != '9')
{
(*p)++;
break;
++ndigits;
++pend; // account for the added most significant digit
}
}
else
{
// Normal increment without rollover
(*q)++;
}
}

// Insert the decimal point
Expand Down Expand Up @@ -910,6 +915,14 @@ static printf_t doprnt(void *context, void (*func)(char c, void *context), size_
}
#endif
#if FEATURE(USE_PRECISION)
// If precision explicitly set to 0 and value is 0, emit a single '0'
if (precision == 0 && uvalue == 0)
{
*--p = '0';
#if FEATURE(USE_ZERO_PAD)
--fwidth;
#endif
}
while (uvalue || precision > 0)
#else
if (uvalue == 0)
Expand Down