digitalmars.D - complex number support
- Walter Bright (6/6) Feb 03 It's becoming clear that I cannot avoid supporting complex numbers in th...
- Richard (Rikki) Andrew Cattermole (4/15) Feb 03 I'm reminded of a certain comment you once made about extern(C++) about
- Walter Bright (2/3) Feb 04 ucent and float16 are a much simpler problem.
- Iain Buclaw (10/18) Feb 04 I've mentioned this before. I might be open to reintroducing
- Quirin Schroll (17/38) Feb 04 Please don’t miss `__imaginary`.
- jmh530 (3/19) Feb 04 What about `core.complex`?
- Walter Bright (4/11) Feb 04 Complex will always have to be supported because of C.
- IchorDev (7/9) Feb 06 On Wednesday, 4 February 2026 at 17:53:49 UTC, Walter Bright
- Quirin Schroll (4/12) Feb 04 Having a built-in complex number types was a major selling point
- Iain Buclaw (9/24) Feb 04 I did the benchmarks with GDC way back when. `std.complex` was
- Walter Bright (2/4) Feb 04 I'm interested in your reasons!
- Quirin Schroll (29/33) Feb 09 I leaned C and C++ as part of a mandatory 2-semester university
- monkyyy (5/8) Feb 09 Hot take, no. They are tuples with strange op overloads thats
- Walter Bright (1/1) Feb 09 It's good to hear the good reasons!
- Timon Gehr (3/7) Feb 15 Apparently that used to exist and was removed:
- Nick Treleaven (19/27) Feb 15 I don't think the logic below still applies:
- Quirin Schroll (15/32) Feb 18 I think the last argument isn’t correct anymore. Absolutely
- Doigt (6/14) Feb 09 I know this is more work for you, but I'm not gonna lie, I'm
-
Walter Bright
(2/5)
Feb 09
It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.
Feb 03
On 04/02/2026 6:14 PM, Walter Bright wrote:It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.I'm reminded of a certain comment you once made about extern(C++) about how it was not worth the effort, until it was a few years later. Both (u)cent and float16 are in the same boat.
Feb 03
On 2/3/2026 9:22 PM, Richard (Rikki) Andrew Cattermole wrote:Both (u)cent and float16 are in the same boat.ucent and float16 are a much simpler problem.
Feb 04
On Wednesday, 4 February 2026 at 05:14:52 UTC, Walter Bright wrote:It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.I've mentioned this before. I might be open to reintroducing complex into the language as `__complex(float)` et al. so that it falls into the specialized category of types that aren't guaranteed to always be supported (whilst at the same time freeing up the old keywords to use as an identifier) We already have the means to test whether `__vector(T)` is supported on a given target, the same style hooks can be used for `__complex(T)`.
Feb 04
On Wednesday, 4 February 2026 at 16:58:42 UTC, Iain Buclaw wrote:On Wednesday, 4 February 2026 at 05:14:52 UTC, Walter Bright wrote:Please don’t miss `__imaginary`. It wouldn’t be too terrible if object.d had this: ```d version(ImaginarySupport) { alias ifloat = __imaginary(float); alias idouble = __imaginary(double); alias ireal = __imaginary(real); } version(ComplexSupport) { alias cfloat = __complex(float); alias cdouble = __complex(double); alias creal = __complex(real); } ```It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.I've mentioned this before. I might be open to reintroducing complex into the language as `__complex(float)` et al. so that it falls into the specialized category of types that aren't guaranteed to always be supported (whilst at the same time freeing up the old keywords to use as an identifier) We already have the means to test whether `__vector(T)` is supported on a given target, the same style hooks can be used for `__complex(T)`.
Feb 04
On Wednesday, 4 February 2026 at 17:19:36 UTC, Quirin Schroll
wrote:
[snip]
It wouldn’t be too terrible if object.d had this:
```d
version(ImaginarySupport)
{
alias ifloat = __imaginary(float);
alias idouble = __imaginary(double);
alias ireal = __imaginary(real);
}
version(ComplexSupport)
{
alias cfloat = __complex(float);
alias cdouble = __complex(double);
alias creal = __complex(real);
}
```
What about `core.complex`?
Feb 04
On 2/4/2026 8:58 AM, Iain Buclaw wrote:I've mentioned this before. I might be open to reintroducing complex into the language as `__complex(float)` et al. so that it falls into the specialized category of types that aren't guaranteed to always be supported (whilst at the same time freeing up the old keywords to use as an identifier) We already have the means to test whether `__vector(T)` is supported on a given target, the same style hooks can be used for `__complex(T)`.Complex will always have to be supported because of C. The vector types have a lot of specific code generator support. I have deferred investigating how to implement it for AArch64 until everything else is working.
Feb 04
On Wednesday, 4 February 2026 at 17:59:19 UTC, Walter Bright wrote:Complex will always have to be supported because of C.On Wednesday, 4 February 2026 at 17:53:49 UTC, Walter Bright wrote:ucent and float16 are a much simpler problem.Then why can't we have `cent`/`ucent`? The library implementations don't have unsigned Int128 and have inconvenient semantics.
Feb 06
On Wednesday, 4 February 2026 at 05:14:52 UTC, Walter Bright wrote:It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.Having a built-in complex number types was a major selling point when I started looking into D ~10 years ago.
Feb 04
On Wednesday, 4 February 2026 at 17:15:49 UTC, Quirin Schroll wrote:On Wednesday, 4 February 2026 at 05:14:52 UTC, Walter Bright wrote:I did the benchmarks with GDC way back when. `std.complex` was just as, or more performant than the built-in types - this can be easily explained as many complex operations are not _actually_ supported in hardware, so become an opaque library call like [__muldc3](https://compiler-explorer.com/z/nx5qEGnfs). The only thing lost was ABI compatibility, hence the special enum types that were added as the compromise.It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.Having a built-in complex number types was a major selling point when I started looking into D ~10 years ago.
Feb 04
On 2/4/2026 9:15 AM, Quirin Schroll wrote:Having a built-in complex number types was a major selling point when I started looking into D ~10 years ago.I'm interested in your reasons!
Feb 04
On Wednesday, 4 February 2026 at 18:00:45 UTC, Walter Bright wrote:On 2/4/2026 9:15 AM, Quirin Schroll wrote:I leaned C and C++ as part of a mandatory 2-semester university course that teaches programming with focus on numerical problems. I aced the exam and became a tutor for it the next years. That was at the time when I discovered D, and noticed several things are much easier in D. I thought of translating the exercises and possible solutions (from German to English and from C++ to D). I ended up discarding that project for lack of time, but it taught me a lot about D. This was before C++11 had widespread support, including user-defined literals for imaginary and complex numbers. Also, C++ has no pure-imaginary types! Maybe it’s the pure mathematician in me, but complex numbers are numbers. And frankly, I never understand what’s the harm in supporting them. C++ can barely get away with an STL implementation and the `std::complex` template has lots of special restrictions and rules on it such as you can reinterpret a `std::complex<T>` as a `T[2]` and a `std::complex<T>[n]` as a `T[2*n]` if I remember correctly. All to be compatible with C’s types, which would be so much easier if it just were a built-in type officially. When I discovered D, I was amazed in a bunch of ways (usually small stuff where it had options to express yourself instead of insisting on one style or another), and it having complex number support was like: Hey, those guys get it. If you want to make D’s imaginary and complex types perfect, allow for an implicit conversion from floating point types to complex types that are bigger. I can’t remember how often I’ve written `+ 0i`.Having a built-in complex number types was a major selling point when I started looking into D ~10 years ago.I'm interested in your reasons!
Feb 09
On Monday, 9 February 2026 at 11:20:14 UTC, Quirin Schroll wrote:Maybe it’s the pure mathematician in me, but complex numbers are numbers.Hot take, no. They are tuples with strange op overloads thats traditional education wildly overvalues and doesn't show other options and pushes wrote rituals when they could show pictures, and teach math as computations.
Feb 09
On 2/9/26 12:20, Quirin Schroll wrote:If you want to make D’s imaginary and complex types perfect, allow for an implicit conversion from floating point types to complex types that are bigger. I can’t remember how often I’ve written `+ 0i`.Apparently that used to exist and was removed: https://forum.dlang.org/post/di2p73$2mgj$1 digitaldaemon.com
Feb 15
On Sunday, 15 February 2026 at 21:04:17 UTC, Timon Gehr wrote:On 2/9/26 12:20, Quirin Schroll wrote:I don't think the logic below still applies: ``` real sin(real x) -- (in user code) -- real w = sin(0.25); float f = somefunc(); // maybe it's in a C library real w2 = sin(f); -------------------- Now we would like to add a complex sine function to std.math creal sin(creal x) ``` The float argument would match both the real and the creal parameter overloads as before. But now we have [partial ordering](https://dlang.org/spec/function.html#partial-ordering) which would find real converts to creal, but creal still would not convert to real, so real is the more specialized overload. So `sin(f)` would call the `sin(real)` overload even if float did convert to cfloat.If you want to make D’s imaginary and complex types perfect, allow for an implicit conversion from floating point types to complex types that are bigger. I can’t remember how often I’ve written `+ 0i`.Apparently that used to exist and was removed: https://forum.dlang.org/post/di2p73$2mgj$1 digitaldaemon.com
Feb 15
On Sunday, 15 February 2026 at 21:04:17 UTC, Timon Gehr wrote:On 2/9/26 12:20, Quirin Schroll wrote:On Thursday, 6 October 2005 at 09:02:28 UTC, Don Clugston wrote:If you want to make D’s imaginary and complex types perfect, allow for an implicit conversion from floating point types to complex types that are bigger. I can’t remember how often I’ve written `+ 0i`.Apparently that used to exist and was removed: https://forum.dlang.org/post/di2p73$2mgj$1 digitaldaemon.com[…] In general, implicit conversions from non-complex to complex types actually *increases* the number of casts required. We'd be better off without them. The underlying problem is that implicit casts mean that a conversion from `float` or `double` to `real` is not considered superior to a conversion to `creal`, so that ambiguities arise very easily. […]I think the last argument isn’t correct anymore. Absolutely no-one is going to ask for an implicit conversion of `cT` to `T` unless VRP can prove it must have an imaginary part of `0i`. So, you have `float` → `real` → `creal`. So, in a situation where a `real` and a `creal` overload compete, the `real` one wins because there’s no generally viable `creal` → `real` conversion. On the other hand, yes, if `cfloat` and `real` compete, they’re both a match with conversion and there’s no conversion between them, so partial ordering can’t determine one of them the best match. I can’t really imagine a situation where you have `f(cfloat)` and `f(double)`/`f(real)`, but not also `f(float)`. This seems to be that kind of situation: “Doctor, it hurts if I hit me knee with a hammer.” — “Don’t do it, then.”
Feb 18
On Wednesday, 4 February 2026 at 05:14:52 UTC, Walter Bright wrote:It's becoming clear that I cannot avoid supporting complex numbers in the code generator for AArch64: 1. deprecating creal and use std.complex instead doesn't help since we need to support old code 2. C has complex real and imaginary real types, which need to be supported as well. I'm giving up and am just going to support complex types in the code generator.I know this is more work for you, but I'm not gonna lie, I'm quite happy for the added support even if I won't be benefiting directly. Though maybe now I'm gonna play with it as I tend to do...
Feb 09
On 2/9/2026 10:54 AM, Doigt wrote:I know this is more work for you, but I'm not gonna lie, I'm quite happy for the added support even if I won't be benefiting directly. Though maybe now I'm gonna play with it as I tend to do...<g>
Feb 09









Walter Bright <newshound2 digitalmars.com> 