1 /**
2  * Implements a complex number type.
3  *
4  * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/complex.d, _complex.d)
8  * Documentation:  https://dlang.org/phobos/dmd_root_complex.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/complex.d
10  */
11 
12 module dmd.root.complex;
13 
14 import dmd.root.ctfloat;
15 
16 nothrow:
17 
18 extern (C++) struct complex_t
19 {
20     real_t re;
21     real_t im;
22 
23   nothrow:
24 
25     this() @disable;
26 
27     this(real_t re)
28     {
29         this(re, CTFloat.zero);
30     }
31 
32     this(real_t re, real_t im) @safe
33     {
34         this.re = re;
35         this.im = im;
36     }
37 
38     extern (D) complex_t opBinary(string op)(complex_t y)
39         if (op == "+")
40     {
41         return complex_t(re + y.re, im + y.im);
42     }
43 
44     extern (D) complex_t opBinary(string op)(complex_t y)
45         if (op == "-")
46     {
47         return complex_t(re - y.re, im - y.im);
48     }
49 
50     extern (D) complex_t opUnary(string op)()
51         if (op == "-")
52     {
53         return complex_t(-re, -im);
54     }
55 
56     extern (D) complex_t opBinary(string op)(complex_t y)
57         if (op == "*")
58     {
59         return complex_t(re * y.re - im * y.im, im * y.re + re * y.im);
60     }
61 
62     extern (D) complex_t opBinaryRight(string op)(real_t x)
63         if (op == "*")
64     {
65         return complex_t(x) * this;
66     }
67 
68     extern (D) complex_t opBinary(string op)(real_t y)
69         if (op == "*")
70     {
71         return this * complex_t(y);
72     }
73 
74     extern (D) complex_t opBinary(string op)(real_t y)
75         if (op == "/")
76     {
77         return this / complex_t(y);
78     }
79 
80     extern (D) complex_t opBinary(string op)(complex_t y)
81         if (op == "/")
82     {
83         if (CTFloat.fabs(y.re) < CTFloat.fabs(y.im))
84         {
85             const r = y.re / y.im;
86             const den = y.im + r * y.re;
87             return complex_t((re * r + im) / den, (im * r - re) / den);
88         }
89         else
90         {
91             const r = y.im / y.re;
92             const den = y.re + r * y.im;
93             return complex_t((re + r * im) / den, (im - r * re) / den);
94         }
95     }
96 
97     extern (D) bool opCast(T : bool)() const
98     {
99         return re || im;
100     }
101 
102     int opEquals(complex_t y) const @safe
103     {
104         return re == y.re && im == y.im;
105     }
106 }
107 
108 extern (C++) real_t creall(complex_t x) @safe
109 {
110     return x.re;
111 }
112 
113 extern (C++) real_t cimagl(complex_t x) @safe
114 {
115     return x.im;
116 }