Description
When using BigInteger.ToString(...) or BigInteger.TryFormat(...) with a format such as 'X' or 'G' using a length specifier, only up to 99 digits can be set for the total format length.
E.g., new BigInteger(42).ToString("X100") fails to properly generate a hexadecimal string with 100 digits, but using 99 works. It results in the following unexpected string instead: X142. And I haven't found any documentation indicating this arbitrary limitation.
Given the size of the numbers typically being used with a type like this, I believe that 99 is not enough for some applications. Especially when using TryFormat and attempting to reduce the number of string/array allocations. Otherwise, awkward or inefficient workarounds are needed (such as using something like new BigInteger(42).ToString("X").PadLeft(100, '0')).
Configuration
.NET 5.0.1 x64 on Windows 10 - does not appear to be specific to any platform.
Regression?
It appears that this issue has been present ever since the file src\libraries\System.Runtime.Numerics\src\System\Numerics\BigNumber.cs was added to this repository. The earliest public .NET reference code I could find (v4.5.1) indicates that it may also have this behavior as well.
Other information
The issue appears to be in the implementation of BigNumber.ParseFormatSpecifier. There is a test inside the parser loop which breaks when n >= 10 causing it to abort, thus only allowing integer values up to 99. Ideally this should be reworked so that any valid positive (or zero) 32-bit signed integer value should be allowed (or at least whatever the internal length limit in ValueStringBuilder is set to), as long as it doesn't overflow.
This does look like it would be a potentially breaking change, but I believe a change in the format parser implementation can be justified since current behavior already results in mangled outputs.
API suggestion
It has been suggested that new API overloads should be introduced to prevent breaking changes to the existing ToString/TryFormat methods.
namespace System.Numerics.BigInteger
{
public struct BigInteger
{
public string ToString(char format, int precision);
public string ToString(char format, int precision, IFormatProvider? provider);
public bool TryFormat(Span<char> destination, out int charsWritten, char format, int precision, IFormatProvider? provider = default);
}
}
Description
When using BigInteger.ToString(...) or BigInteger.TryFormat(...) with a format such as 'X' or 'G' using a length specifier, only up to 99 digits can be set for the total format length.
E.g.,
new BigInteger(42).ToString("X100")fails to properly generate a hexadecimal string with 100 digits, but using 99 works. It results in the following unexpected string instead:X142. And I haven't found any documentation indicating this arbitrary limitation.Given the size of the numbers typically being used with a type like this, I believe that 99 is not enough for some applications. Especially when using TryFormat and attempting to reduce the number of string/array allocations. Otherwise, awkward or inefficient workarounds are needed (such as using something like
new BigInteger(42).ToString("X").PadLeft(100, '0')).Configuration
.NET 5.0.1 x64 on Windows 10 - does not appear to be specific to any platform.
Regression?
It appears that this issue has been present ever since the file
src\libraries\System.Runtime.Numerics\src\System\Numerics\BigNumber.cswas added to this repository. The earliest public .NET reference code I could find (v4.5.1) indicates that it may also have this behavior as well.Other information
The issue appears to be in the implementation of
BigNumber.ParseFormatSpecifier. There is a test inside the parser loop which breaks whenn >= 10causing it to abort, thus only allowing integer values up to 99. Ideally this should be reworked so that any valid positive (or zero) 32-bit signed integer value should be allowed (or at least whatever the internal length limit inValueStringBuilderis set to), as long as it doesn't overflow.This does look like it would be a potentially breaking change, but I believe a change in the format parser implementation can be justified since current behavior already results in mangled outputs.
API suggestion
It has been suggested that new API overloads should be introduced to prevent breaking changes to the existing
ToString/TryFormatmethods.