diff --git a/src/CLR/CorLib/corlib_native_System_Number.cpp b/src/CLR/CorLib/corlib_native_System_Number.cpp index 34a9939a03..f1c048d5a3 100644 --- a/src/CLR/CorLib/corlib_native_System_Number.cpp +++ b/src/CLR/CorLib/corlib_native_System_Number.cpp @@ -705,6 +705,28 @@ int Library_corlib_native_System_Number::Format_F( bool isIntegerDataType = IsIntegerDataType(dataType); + // For floating-point types with precision 0, check if we have negative zero case + // This happens when a small negative value (e.g., -0.099) rounds to 0 + bool isNegativeZeroCase = false; + if (!isIntegerDataType && precision == 0) + { + double val = 0.0; + if (dataType == DATATYPE_R4) + { + val = (double)value->NumericByRef().r4; + } + else if (dataType == DATATYPE_R8) + { + val = (double)value->NumericByRef().r8; + } + + // Check if value is negative and would round to 0 with precision 0 + if (val < 0.0 && val > -0.5) + { + isNegativeZeroCase = true; + } + } + char formatStr[FORMAT_FMTSTR_BUFFER_SIZE]; snprintf( formatStr, @@ -756,6 +778,28 @@ int Library_corlib_native_System_Number::Format_F( ret = ReplaceNegativeSign(buffer, ret, negativeSign); ret = ReplaceDecimalSeparator(buffer, ret, decimalSeparator); } + else if (isIntegerDataType && ret == 0) + { + // special case: when precision is 0 and value is 0, snprintf returns empty string + // we need to output "0" instead + buffer[0] = '0'; + buffer[1] = 0; + ret = 1; + } + // apply culture-specific replacements for floating-point types + else if (!isIntegerDataType && ret > 0) + { + // handle negative zero: if the value was negative but rounds to 0, remove the minus sign + if (isNegativeZeroCase && buffer[0] == '-') + { + // remove the negative sign + memmove(buffer, &buffer[1], ret); + ret--; + } + + ret = ReplaceNegativeSign(buffer, ret, negativeSign); + ret = ReplaceDecimalSeparator(buffer, ret, decimalSeparator); + } return ret; }