1use crate::num::imp::libm::complex::*;
2use crate::ops::{Add, Div, Mul, Neg, Sub};
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6#[unstable(feature = "complex_numbers", issue = "154023")]
7#[repr(C)]
8#[lang = "complex"]
9pub struct Complex<T> {
10 pub re: T,
12 pub im: T,
14}
15
16#[unstable(feature = "complex_numbers", issue = "154023")]
17impl<T> Complex<T> {
18 #[must_use]
20 pub const fn new(re: T, im: T) -> Complex<T> {
21 Complex { re, im }
22 }
23}
24
25#[unstable(feature = "complex_numbers", issue = "154023")]
26impl<T: Default> Default for Complex<T> {
27 fn default() -> Self {
28 Self { re: Default::default(), im: Default::default() }
29 }
30}
31
32#[unstable(feature = "complex_numbers", issue = "154023")]
33impl<T> Complex<T>
34where
35 T: Neg<Output = T>,
36{
37 #[must_use]
42 pub fn conjugate(self) -> Self {
43 Complex { re: self.re, im: -self.im }
44 }
45}
46
47#[unstable(feature = "complex_numbers", issue = "154023")]
48impl<T: Neg> Neg for Complex<T> {
49 type Output = Complex<T::Output>;
50
51 fn neg(self) -> Self::Output {
56 Complex::new(-self.re, -self.im)
57 }
58}
59
60#[unstable(feature = "complex_numbers", issue = "154023")]
61impl<T: Add> Add<Self> for Complex<T> {
62 type Output = Complex<T::Output>;
63
64 fn add(self, rhs: Self) -> Self::Output {
65 Complex::new(self.re + rhs.re, self.im + rhs.im)
66 }
67}
68
69#[unstable(feature = "complex_numbers", issue = "154023")]
70impl<T: Add<Output = T>> Add<T> for Complex<T> {
71 type Output = Complex<T::Output>;
72
73 fn add(self, rhs: T) -> Self::Output {
74 Complex::new(self.re + rhs, self.im)
75 }
76}
77
78#[unstable(feature = "complex_numbers", issue = "154023")]
79impl<T: Sub> Sub<Self> for Complex<T> {
80 type Output = Complex<T::Output>;
81
82 fn sub(self, rhs: Self) -> Self::Output {
83 Complex::new(self.re - rhs.re, self.im - rhs.im)
84 }
85}
86
87#[unstable(feature = "complex_numbers", issue = "154023")]
88impl<T: Sub<Output = T>> Sub<T> for Complex<T> {
89 type Output = Complex<T::Output>;
90
91 fn sub(self, rhs: T) -> Self::Output {
92 Complex::new(self.re - rhs, self.im)
93 }
94}
95
96macro_rules! impl_complex_mul_div {
97 ($ty:ty, $mul:ident, $div:ident) => {
98 #[unstable(feature = "complex_numbers", issue = "154023")]
99 impl Mul for Complex<$ty> {
100 type Output = Self;
101
102 #[inline]
103 fn mul(self, rhs: Self) -> Self::Output {
104 let Complex { re: a, im: b } = self;
105 let Complex { re: c, im: d } = rhs;
106
107 let ac = a * c;
108 let bd = b * d;
109 let ad = a * d;
110 let bc = b * c;
111
112 let z = Complex::new(ac - bd, ad + bc);
113
114 if z.re.is_nan() && z.im.is_nan() {
122 crate::hint::cold_path();
123 $mul(a, b, c, d)
124 } else {
125 z
126 }
127 }
128 }
129
130 #[unstable(feature = "complex_numbers", issue = "154023")]
131 impl Div for Complex<$ty> {
132 type Output = Self;
133
134 #[inline]
135 fn div(self, rhs: Self) -> Self::Output {
136 $div(self.re, self.im, rhs.re, rhs.im)
137 }
138 }
139 };
140}
141
142impl_complex_mul_div!(f16, __rust_mulhc3, __rust_divhc3);
143impl_complex_mul_div!(f32, __mulsc3, __divsc3);
144impl_complex_mul_div!(f64, __muldc3, __divdc3);
145impl_complex_mul_div!(f128, __rust_multc3, __rust_divtc3);