Skip to content

API suggestion: Provide an overload of System.Numerics.BigInteger.ToString()/TryFormat() that allows precision greater than 99 #46440

@assumenothing

Description

@assumenothing

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);
    }
}

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions