數值格式字串的最大精確度
使用 ToString
和 TryFormat
將數字格式化為字串時的最大有效位數,已從 Int32.MaxValue 變更為 999,999,999。 (先前在 .NET 6 中,最大有效位數已變更為 Int32.MaxValue。)
此外,從字串剖析 BigInteger 時,允許的最大指數限制為 999,999,999。
先前的行為
在 .NET 6 中,標準數值格式剖析邏輯限制為 Int32.MaxValue 個以下的有效位數。 預期的行為是針對大於 Int32.MaxValue 的任何有效位數擲回 FormatException。 不過,因為錯誤 (bug) 的關係,.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,999,999,則會擲回 FormatException。 這項變更是在影響所有數值類型的剖析邏輯中實作。
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 的指數,則會擲回 FormatException。
導入的版本
.NET 7
中斷性變更的類型
這項變更會影響二進位相容性。
變更原因
在 .NET 6 中引進的行為,是為了針對任何大於 Int32.MaxValue 的有效位數擲回 FormatException。 不過,由於錯誤 (bug) 的關係,而未針對某些大於最大值的輸入擲回例外狀況。 這項變更會將有效位數限制為 999,999,999,以修正錯誤 (bug)。
建議的動作
在大部分情況下,不需要採取任何動作,因為您不太可能在格式字串中使用高於 999,999,999 的有效位數。
受影響的 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)