Skip to content

Commit 60feff8

Browse files
authored
Document breaking change: Complex special-value results now follow C23 Annex G (#55230)
1 parent 277d0d8 commit 60feff8

3 files changed

Lines changed: 82 additions & 0 deletions

File tree

docs/core/compatibility/11.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ See [Breaking changes in ASP.NET Core 11](/aspnet/core/breaking-changes/11/overv
2323
| Title | Type of change |
2424
|-------------------------------------------------------------------|-------------------|
2525
| [CborReader and CborWriter enforce a default maximum nesting depth](core-libraries/11/cbor-max-depth.md) | Behavioral change |
26+
| [Complex special-value results now follow C23 Annex G](core-libraries/11/complex-annex-g-special-values.md) | Behavioral change |
2627
| [CRC32 validation added when reading ZIP archive entries](core-libraries/11/ziparchive-entry-crc32-validation.md) | Behavioral change |
2728
| [DateOnly and TimeOnly TryParse methods throw for invalid input](core-libraries/11/dateonly-timeonly-tryparse-argumentexception.md) | Behavioral change |
2829
| [DeflateStream and GZipStream write headers and footers for empty payload](core-libraries/11/deflatestream-gzipstream-empty-payload.md) | Behavioral change |
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
title: "Breaking change: System.Numerics.Complex special-value results now follow C23 Annex G"
3+
description: "Learn about the breaking change in .NET 11 where System.Numerics.Complex arithmetic and math functions return C23 Annex G-conformant special values for signed zeros, infinities, and NaNs."
4+
ms.date: 08/04/2026
5+
ai-usage: ai-assisted
6+
---
7+
8+
# System.Numerics.Complex special-value results now follow C23 Annex G
9+
10+
<xref:System.Numerics.Complex> arithmetic operators and math functions now produce the special-value results (for signed zeros, infinities, and NaNs) required by C23 Annex G (IEC 60559-compatible complex arithmetic). Because `Complex` now delegates most of its implementation to the new `Complex<double>` type, the conformant special-value handling flows through to it.
11+
12+
## Version introduced
13+
14+
.NET 11 Preview 7
15+
16+
## Previous behavior
17+
18+
Previously, for non-finite (and some overflowing) inputs, `Complex` arithmetic and elementary functions frequently returned `(NaN, NaN)` even when a directed infinity or signed result was mathematically appropriate.
19+
20+
```csharp
21+
using System.Numerics;
22+
23+
Complex.Atan(new Complex(double.PositiveInfinity, 1.0)); // (NaN, NaN)
24+
Complex.Acos(new Complex(double.NegativeInfinity, double.NaN)); // (NaN, NaN)
25+
Complex.Cosh(new Complex(double.PositiveInfinity, double.PositiveInfinity)); // (NaN, NaN)
26+
27+
// An infinite operand could collapse the product to NaN:
28+
new Complex(double.PositiveInfinity, double.PositiveInfinity) * new Complex(1.0, 0.0); // (NaN, NaN)
29+
```
30+
31+
## New behavior
32+
33+
Starting in .NET 11, the same inputs return the C23 Annex G special values.
34+
35+
```csharp
36+
using System.Numerics;
37+
38+
Complex.Atan(new Complex(double.PositiveInfinity, 1.0)); // (π/2, 0)
39+
Complex.Acos(new Complex(double.NegativeInfinity, double.NaN)); // (NaN, +∞)
40+
Complex.Cosh(new Complex(double.PositiveInfinity, double.PositiveInfinity)); // (+∞, NaN)
41+
42+
// An infinite operand now yields a directed infinity (Annex G.5.1 recovery):
43+
new Complex(double.PositiveInfinity, double.PositiveInfinity) * new Complex(1.0, 0.0); // (+∞, +∞)
44+
```
45+
46+
Division by a zero divisor is likewise governed by Annex G: the result is a directed infinity, or NaN for `0/0`. For example, `(1, 0) / (0, 0)` yields an infinite real component rather than a fully NaN result.
47+
48+
The change spans `operator *`, `operator /`, `Multiply`, `Divide`, `Reciprocal`, `Abs`, `Pow`, and the elementary functions (`Sqrt`, `Exp`, `Log`, `Log10`, and the trigonometric, hyperbolic, and inverse-trigonometric functions). One case Annex G leaves explicitly unspecified, that is, the sign of a zero-valued quotient component from `operator /`, might also differ.
49+
50+
## Type of breaking change
51+
52+
This change is a [behavioral change](../../categories.md#behavioral-change).
53+
54+
## Reason for change
55+
56+
Complex numbers are outside the scope of IEEE 754 itself, so C23 Annex G is the relevant specification of the special-value behavior IEEE 754 otherwise implies for the scalar operations complex arithmetic is built on. The previous implementation returned `NaN` for many inputs where Annex G requires a directed infinity or a signed result, which is both non-conformant and less useful for downstream numerical code, because it lost the sign or direction information that an infinite intermediate value carries. The new generic `Complex<T>` type was made conformant, and the shipped `Complex` type inherits that conformance by delegation.
57+
58+
For more information, see [dotnet/runtime#131132](https://github.com/dotnet/runtime/pull/131132).
59+
60+
## Recommended action
61+
62+
Most code benefits from the more accurate results and needs no change. If your code explicitly depends on the previous `(NaN, NaN)` results for special-value inputs, update it to expect the Annex G values. Such code might be tests that assert `NaN` for `Complex` operations on infinities, or logic that treats any non-finite input as producing `NaN`.
63+
64+
There's no compatibility switch to restore the previous behavior.
65+
66+
## Affected APIs
67+
68+
- <xref:System.Numerics.Complex.op_Multiply(System.Numerics.Complex,System.Numerics.Complex)?displayProperty=nameWithType>
69+
- <xref:System.Numerics.Complex.op_Division(System.Numerics.Complex,System.Numerics.Complex)?displayProperty=nameWithType>
70+
- <xref:System.Numerics.Complex.Multiply(System.Numerics.Complex,System.Numerics.Complex)?displayProperty=nameWithType>
71+
- <xref:System.Numerics.Complex.Divide(System.Numerics.Complex,System.Numerics.Complex)?displayProperty=nameWithType>
72+
- <xref:System.Numerics.Complex.Reciprocal(System.Numerics.Complex)?displayProperty=nameWithType>
73+
- <xref:System.Numerics.Complex.Abs(System.Numerics.Complex)?displayProperty=nameWithType>
74+
- <xref:System.Numerics.Complex.Pow(System.Numerics.Complex,System.Numerics.Complex)?displayProperty=nameWithType> and <xref:System.Numerics.Complex.Pow(System.Numerics.Complex,System.Double)?displayProperty=nameWithType>
75+
- <xref:System.Numerics.Complex.Sqrt(System.Numerics.Complex)?displayProperty=nameWithType>
76+
- <xref:System.Numerics.Complex.Exp(System.Numerics.Complex)?displayProperty=nameWithType>
77+
- <xref:System.Numerics.Complex.Log(System.Numerics.Complex)?displayProperty=nameWithType> (all overloads) and <xref:System.Numerics.Complex.Log10(System.Numerics.Complex)?displayProperty=nameWithType>
78+
- <xref:System.Numerics.Complex.Sin(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Cos(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Tan(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Sinh(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Cosh(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Tanh(System.Numerics.Complex)?displayProperty=nameWithType>
79+
- <xref:System.Numerics.Complex.Asin(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Acos(System.Numerics.Complex)?displayProperty=nameWithType>, <xref:System.Numerics.Complex.Atan(System.Numerics.Complex)?displayProperty=nameWithType>

docs/core/compatibility/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ items:
1212
items:
1313
- name: CborReader and CborWriter enforce a default maximum nesting depth
1414
href: core-libraries/11/cbor-max-depth.md
15+
- name: Complex special-value results now follow C23 Annex G
16+
href: core-libraries/11/complex-annex-g-special-values.md
1517
- name: CRC32 validation added when reading ZIP archive entries
1618
href: core-libraries/11/ziparchive-entry-crc32-validation.md
1719
- name: DateOnly and TimeOnly TryParse methods throw for invalid input

0 commit comments

Comments
 (0)