Максимальная точность для строк числового формата
Максимальная точность при форматировании чисел в виде строк и ToString
TryFormat
была изменена на Int32.MaxValue 999 999 999 999. (Максимальная точность ранее была изменена на Int32.MaxValue .NET 6.)
Кроме того, максимально допустимое экспонентное значение при синтаксическом анализе BigInteger строки ограничено 999 999 999 999.
Прежнее поведение
В .NET 6 логика синтаксического анализа стандартного числового формата была ограничена точностью Int32.MaxValue или меньшей точностью. Предполагаемое поведение было вызывать FormatException для любой точности больше Int32.MaxValue. Однако из-за ошибки .NET 6 не создает это исключение для некоторых таких входных данных. Предполагаемое поведение было следующим:
double d = 123.0;
d.ToString("E" + int.MaxValue.ToString()); // Doesn't throw.
long intMaxPlus1 = (long)int.MaxValue + 1;
string intMaxPlus1String = intMaxPlus1.ToString();
Assert.Throws<FormatException>(() => d.ToString("E" + intMaxPlus1String)); // Throws.
Кроме того, при синтаксическом анализе BigInteger из строки не было ограничения на экспонентный размер.
Новое поведение
Начиная с .NET 7, .NET поддерживает точность до 999 999 999 999. Возникает FormatException , если точность превышает 999 999 999 999 999. Это изменение было реализовано в логике анализа, которая влияет на все числовые типы.
double d = 123.0;
Assert.Throws<FormatException>(() => d.ToString("E" + int.MaxValue.ToString())); // Throws.
long intMaxPlus1 = (long)int.MaxValue + 1;
string intMaxPlus1String = intMaxPlus1.ToString();
Assert.Throws<FormatException>(() => d.ToString("E" + intMaxPlus1String)); // Throws.
d.ToString("E999999999"); // Doesn't throw.
d.ToString("E00000999999999"); // Doesn't throw.
Кроме того, если вы пытаетесь проанализировать объект BigInteger с экспонентом больше 999 999 999 999 из строки, FormatException создается исключение.
Представленные версии
.NET 7
Тип критического изменения
Это изменение может повлиять на совместимость двоичного кода.
Причина изменения
Поведение, введенное в .NET 6, было предназначено для создания FormatException любой точности больше, чем Int32.MaxValue. Однако из-за ошибки исключение для некоторых входных данных больше максимального размера не было. Это изменение исправляет ошибку путем ограничения точности до 999 999 999 999.
Рекомендуемое действие
В большинстве случаев никаких действий не требуется, так как вряд ли вы уже используете точность выше 999 999 999 999999 в строках формата.
Затронутые API
Это изменение было реализовано в логике анализа, которая влияет на все числовые типы.
- System.Numerics.BigInteger.ToString(String)
- System.Numerics.BigInteger.ToString(String, IFormatProvider)
- System.Numerics.BigInteger.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Int32.ToString(String)
- System.Int32.ToString(String, IFormatProvider)
- System.Int32.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.UInt32.ToString(String)
- System.UInt32.ToString(String, IFormatProvider)
- System.UInt32.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Byte.ToString(String)
- System.Byte.ToString(String, IFormatProvider)
- System.Byte.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.SByte.ToString(String)
- System.SByte.ToString(String, IFormatProvider)
- System.SByte.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Int16.ToString(String)
- System.Int16.ToString(String, IFormatProvider)
- System.Int16.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.UInt16.ToString(String)
- System.UInt16.ToString(String, IFormatProvider)
- System.UInt16.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Numerics.BigInteger.Parse
- System.Numerics.BigInteger.TryParse
- System.Int64.ToString(String)
- System.Int64.ToString(String, IFormatProvider)
- System.Int64.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.UInt64.ToString(String)
- System.UInt64.ToString(String, IFormatProvider)
- System.UInt64.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Half.ToString(String)
- System.Half.ToString(String, IFormatProvider)
- System.Half.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Single.ToString(String)
- System.Single.ToString(String, IFormatProvider)
- System.Single.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Double.ToString(String)
- System.Double.ToString(String, IFormatProvider)
- System.Double.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Decimal.ToString(String)
- System.Decimal.ToString(String, IFormatProvider)
- System.Decimal.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)