www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - complex number support

reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
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
parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling next sibling parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
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
next sibling parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
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:
 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)`.
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); } ```
Feb 04
parent jmh530 <john.michael.hall gmail.com> writes:
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
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent IchorDev <zxinsworld gmail.com> writes:
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
prev sibling next sibling parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
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
next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
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:
 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.
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.
Feb 04
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Wednesday, 4 February 2026 at 18:00:45 UTC, Walter Bright 
wrote:
 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!
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`.
Feb 09
next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
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
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
It's good to hear the good reasons!
Feb 09
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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
next sibling parent Nick Treleaven <nick geany.org> writes:
On Sunday, 15 February 2026 at 21:04:17 UTC, Timon Gehr wrote:
 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
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.
Feb 15
prev sibling parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Sunday, 15 February 2026 at 21:04:17 UTC, Timon Gehr wrote:
 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
On Thursday, 6 October 2005 at 09:02:28 UTC, Don Clugston wrote:
 […]
 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
prev sibling parent reply Doigt <labog outlook.com> writes:
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
parent Walter Bright <newshound2 digitalmars.com> writes:
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