fend_core/num/
complex.rs

1use crate::DecimalSeparatorStyle;
2use crate::error::{FendError, Interrupt};
3use crate::num::Exact;
4use crate::num::real::{self, Real};
5use crate::num::{Base, FormattingStyle};
6use crate::result::FResult;
7use crate::serialize::CborValue;
8use std::cmp::Ordering;
9use std::fmt;
10use std::ops::Neg;
11
12#[derive(Clone, Hash)]
13pub(crate) struct Complex {
14	real: Real,
15	imag: Real,
16}
17
18impl fmt::Debug for Complex {
19	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20		write!(f, "{:?}", self.real)?;
21		if !self.imag.is_definitely_zero() {
22			write!(f, " + {:?}i", self.imag)?;
23		}
24		Ok(())
25	}
26}
27
28#[derive(Copy, Clone, Eq, PartialEq)]
29pub(crate) enum UseParentheses {
30	No,
31	IfComplex,
32	IfComplexOrFraction,
33}
34
35impl Complex {
36	pub(crate) fn compare<I: Interrupt>(&self, other: &Self, int: &I) -> FResult<Option<Ordering>> {
37		if self.imag().is_zero() && other.imag().is_zero() {
38			Ok(Some(self.real().compare(&other.real(), int)?))
39		} else {
40			Ok(None)
41		}
42	}
43
44	pub(crate) fn serialize(&self) -> CborValue {
45		let real = self.real.serialize();
46		if self.imag.is_zero() {
47			real
48		} else {
49			let imag = self.imag.serialize();
50			CborValue::Tag(43000, Box::new(CborValue::Array(vec![real, imag])))
51		}
52	}
53
54	pub(crate) fn deserialize(value: CborValue) -> FResult<Self> {
55		Ok(match value {
56			CborValue::Tag(43000, inner) => {
57				if let CborValue::Array(arr) = *inner
58					&& arr.len() == 2
59				{
60					let mut arr = arr.into_iter();
61					let real = Real::deserialize(arr.next().unwrap())?;
62					let imag = Real::deserialize(arr.next().unwrap())?;
63					Self { real, imag }
64				} else {
65					return Err(FendError::DeserializationError(
66						"tag 43000 must contain a length-2 array",
67					));
68				}
69			}
70			value => {
71				let real = Real::deserialize(value)?;
72				Self {
73					real,
74					imag: 0.into(),
75				}
76			}
77		})
78	}
79
80	pub(crate) fn try_as_real(self) -> FResult<Real> {
81		if !self.imag.is_zero() {
82			return Err(FendError::ComplexToInteger);
83		}
84		Ok(self.real)
85	}
86
87	pub(crate) fn try_as_usize<I: Interrupt>(self, int: &I) -> FResult<usize> {
88		if !self.imag.is_zero() {
89			return Err(FendError::ComplexToInteger);
90		}
91		self.real.try_as_usize(int)
92	}
93
94	pub(crate) fn try_as_i64<I: Interrupt>(self, int: &I) -> FResult<i64> {
95		if !self.imag.is_zero() {
96			return Err(FendError::ComplexToInteger);
97		}
98		self.real.try_as_i64(int)
99	}
100
101	#[inline]
102	pub(crate) fn real(&self) -> Real {
103		self.real.clone()
104	}
105
106	#[inline]
107	pub(crate) fn imag(&self) -> Real {
108		self.imag.clone()
109	}
110
111	pub(crate) fn conjugate(self) -> Self {
112		Self {
113			real: self.real,
114			imag: -self.imag,
115		}
116	}
117
118	pub(crate) fn factorial<I: Interrupt>(self, int: &I) -> FResult<Self> {
119		if !self.imag.is_zero() {
120			return Err(FendError::FactorialComplex);
121		}
122		Ok(Self {
123			real: self.real.factorial(int)?,
124			imag: self.imag,
125		})
126	}
127
128	pub(crate) fn exp<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
129		// e^(a + bi) = e^a * e^(bi) = e^a * (cos(b) + i * sin(b))
130		let r = self.real.exp(int)?;
131		let exact = r.exact;
132
133		Ok(Exact::new(
134			Self {
135				real: r.clone().mul(self.imag.clone().cos(int)?.re(), int)?.value,
136				imag: r.mul(self.imag.sin(int)?.re(), int)?.value,
137			},
138			exact,
139		))
140	}
141
142	fn pow_n<I: Interrupt>(self, n: usize, int: &I) -> FResult<Exact<Self>> {
143		if n == 0 {
144			return Ok(Exact::new(Self::from(1), true));
145		}
146
147		let mut result = Exact::new(Self::from(1), true);
148		let mut base = Exact::new(self, true);
149		let mut exp = n;
150		while exp > 0 {
151			if exp & 1 == 1 {
152				result = result.mul(&base, int)?;
153			}
154			base = base.clone().mul(&base, int)?;
155			exp >>= 1;
156		}
157
158		Ok(result)
159	}
160
161	pub(crate) fn pow<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Exact<Self>> {
162		if !rhs.real.is_integer() || !rhs.imag.is_integer() {
163			return self.frac_pow(rhs, int);
164		}
165
166		if self.imag.is_zero() && rhs.imag.is_zero() {
167			let real = self.real.pow(rhs.real, int)?;
168			Ok(Exact::new(
169				Self {
170					real: real.value,
171					imag: 0.into(),
172				},
173				real.exact,
174			))
175		} else {
176			let rem = rhs.clone().real.modulo(4.into(), int);
177			// Reduced case: (ix)^y = x^y * i^y
178			if self.real.is_zero() && rhs.imag.is_zero() {
179				if let Ok(n) = rhs.real.try_as_usize(int) {
180					return self.pow_n(n, int);
181				}
182
183				let mut result = Exact::new(
184					match rem.and_then(|rem| rem.try_as_usize(int)) {
185						Ok(0) => 1.into(),
186						Ok(1) => Self {
187							real: 0.into(),
188							imag: 1.into(),
189						},
190						Ok(2) => Self {
191							real: Real::from(1).neg(),
192							imag: 0.into(),
193						},
194						Ok(3) => Self {
195							real: 0.into(),
196							imag: Real::from(1).neg(),
197						},
198						Ok(_) | Err(_) => unreachable!("modulo 4 should always be 0, 1, 2, or 3"),
199					},
200					true,
201				);
202
203				if !self.imag.is_definitely_one() {
204					result = self
205						.imag
206						.pow(2.into(), int)?
207						.apply(Self::from)
208						.mul(&result, int)?;
209				}
210
211				return Ok(result);
212			}
213
214			// z^w = e^(w * ln(z))
215			let exp = self.ln(int)?.mul(&Exact::new(rhs, true), int)?;
216			Ok(exp.value.exp(int)?.combine(exp.exact))
217		}
218	}
219
220	pub(crate) fn i() -> Self {
221		Self {
222			real: 0.into(),
223			imag: 1.into(),
224		}
225	}
226
227	pub(crate) fn pi() -> Self {
228		Self {
229			real: Real::pi(),
230			imag: 0.into(),
231		}
232	}
233
234	pub(crate) fn abs<I: Interrupt>(self, int: &I) -> FResult<Exact<Real>> {
235		Ok(if self.imag.is_zero() {
236			if self.real.is_neg() {
237				Exact::new(-self.real, true)
238			} else {
239				Exact::new(self.real, true)
240			}
241		} else if self.real.is_zero() {
242			if self.imag.is_neg() {
243				Exact::new(-self.imag, true)
244			} else {
245				Exact::new(self.imag, true)
246			}
247		} else {
248			let power = self.real.pow(2.into(), int)?;
249			let power2 = self.imag.pow(2.into(), int)?;
250			let real = power.add(power2, int)?;
251			let result = real.value.root_n(&Real::from(2), int)?;
252			result.combine(real.exact)
253		})
254	}
255
256	pub(crate) fn floor<I: Interrupt>(self, int: &I) -> FResult<Exact<Real>> {
257		Ok(Exact::new(self.expect_real()?.floor(int)?, true))
258	}
259
260	pub(crate) fn ceil<I: Interrupt>(self, int: &I) -> FResult<Exact<Real>> {
261		Ok(Exact::new(self.expect_real()?.ceil(int)?, true))
262	}
263
264	pub(crate) fn round<I: Interrupt>(self, int: &I) -> FResult<Exact<Real>> {
265		Ok(Exact::new(self.expect_real()?.round(int)?, true))
266	}
267
268	pub(crate) fn arg<I: Interrupt>(self, int: &I) -> FResult<Exact<Real>> {
269		Ok(Exact::new(self.imag.atan2(self.real, int)?, false))
270	}
271
272	pub(crate) fn format<I: Interrupt>(
273		&self,
274		exact: bool,
275		style: FormattingStyle,
276		base: Base,
277		use_parentheses: UseParentheses,
278		decimal_separator: DecimalSeparatorStyle,
279		int: &I,
280	) -> FResult<Exact<Formatted>> {
281		let style = if !self.imag.is_zero() && style == FormattingStyle::Auto {
282			FormattingStyle::Exact
283		} else {
284			style
285		};
286
287		if self.imag.is_zero() {
288			let use_parens = use_parentheses == UseParentheses::IfComplexOrFraction;
289			let x = self
290				.real
291				.format(base, style, false, use_parens, decimal_separator, int)?;
292			return Ok(Exact::new(
293				Formatted {
294					first_component: x.value,
295					separator: "",
296					second_component: None,
297					use_parentheses: false,
298				},
299				exact && x.exact,
300			));
301		}
302
303		Ok(if self.real.is_zero() {
304			let use_parens = use_parentheses == UseParentheses::IfComplexOrFraction;
305			let x = self
306				.imag
307				.format(base, style, true, use_parens, decimal_separator, int)?;
308			Exact::new(
309				Formatted {
310					first_component: x.value,
311					separator: "",
312					second_component: None,
313					use_parentheses: false,
314				},
315				exact && x.exact,
316			)
317		} else {
318			let mut exact = exact;
319			let real_part = self
320				.real
321				.format(base, style, false, false, decimal_separator, int)?;
322			exact = exact && real_part.exact;
323			let (positive, imag_part) = if self.imag.is_pos() {
324				(
325					true,
326					self.imag
327						.format(base, style, true, false, decimal_separator, int)?,
328				)
329			} else {
330				(
331					false,
332					(-self.imag.clone()).format(
333						base,
334						style,
335						true,
336						false,
337						decimal_separator,
338						int,
339					)?,
340				)
341			};
342			exact = exact && imag_part.exact;
343			let separator = if positive { " + " } else { " - " };
344			Exact::new(
345				Formatted {
346					first_component: real_part.value,
347					separator,
348					second_component: Some(imag_part.value),
349					use_parentheses: use_parentheses == UseParentheses::IfComplex
350						|| use_parentheses == UseParentheses::IfComplexOrFraction,
351				},
352				exact,
353			)
354		})
355	}
356	pub(crate) fn frac_pow<I: Interrupt>(self, n: Self, int: &I) -> FResult<Exact<Self>> {
357		if self.imag.is_zero() && n.imag.is_zero() && !self.real.is_neg() {
358			Ok(self.real.pow(n.real, int)?.apply(Self::from))
359		} else {
360			let exponent = self.ln(int)?.mul(&Exact::new(n, true), int)?;
361			Ok(exponent.value.exp(int)?.combine(exponent.exact))
362		}
363	}
364
365	fn expect_real(self) -> FResult<Real> {
366		if self.imag.is_zero() {
367			Ok(self.real)
368		} else {
369			Err(FendError::ExpectedARealNumber)
370		}
371	}
372
373	pub(crate) fn sin<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
374		// sin(a + bi) = sin(a) * cosh(b) + i * cos(a) * sinh(b)
375		if self.imag.is_zero() {
376			Ok(self.real.sin(int)?.apply(Self::from))
377		} else {
378			let cosh = Exact::new(self.imag.clone().cosh(int)?, false);
379			let sinh = Exact::new(self.imag.sinh(int)?, false);
380
381			let real = self.real.clone().sin(int)?.mul(cosh.re(), int)?;
382			let imag = self.real.cos(int)?.mul(sinh.re(), int)?;
383
384			Ok(Exact::new(
385				Self {
386					real: real.value,
387					imag: imag.value,
388				},
389				real.exact && imag.exact,
390			))
391		}
392	}
393
394	pub(crate) fn cos<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
395		// cos(a + bi) = cos(a) * cosh(b) - i * sin(a) * sinh(b)
396		if self.imag.is_zero() {
397			Ok(self.real.cos(int)?.apply(Self::from))
398		} else {
399			let cosh = Exact::new(self.imag.clone().cosh(int)?, false);
400			let sinh = Exact::new(self.imag.sinh(int)?, false);
401			let exact_real = Exact::new(self.real, true);
402
403			let real = exact_real.value.clone().cos(int)?.mul(cosh.re(), int)?;
404			let imag = exact_real.value.sin(int)?.mul(sinh.re(), int)?.neg();
405			Ok(Exact::new(
406				Self {
407					real: real.value,
408					imag: imag.value,
409				},
410				real.exact && imag.exact,
411			))
412		}
413	}
414
415	pub(crate) fn tan<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
416		let num = self.clone().sin(int)?;
417		let den = self.cos(int)?;
418		num.div(den, int)
419	}
420
421	/// Calculates ln(i * z + sqrt(1 - z^2))
422	/// This is used to implement asin and acos for all complex numbers
423	fn asin_ln<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
424		let half = Exact::new(Self::from(1), true).div(Exact::new(Self::from(2), true), int)?;
425		let exact = Exact::new(self, true);
426		let i = Exact::new(Self::i(), true);
427
428		let sqrt = Exact::new(Self::from(1), true)
429			.add(exact.clone().mul(&exact, int)?.neg(), int)?
430			.try_and_then(|x| x.frac_pow(half.value, int))?;
431		i.mul(&exact, int)?
432			.add(sqrt, int)?
433			.try_and_then(|x| x.ln(int))
434	}
435
436	pub(crate) fn asin<I: Interrupt>(self, int: &I) -> FResult<Self> {
437		// Real asin is defined for -1 <= x <= 1
438		if self.imag.is_zero() && self.real.between_plus_minus_one_incl(int)? {
439			Ok(Self::from(self.real.asin(int)?))
440		} else {
441			// asin(z) = -i * ln(i * z + sqrt(1 - z^2))
442			Ok(self
443				.asin_ln(int)?
444				.mul(&Exact::new(Self::i(), true), int)?
445				.neg()
446				.value)
447		}
448	}
449
450	pub(crate) fn acos<I: Interrupt>(self, int: &I) -> FResult<Self> {
451		// Real acos is defined for -1 <= x <= 1
452		if self.imag.is_zero() && self.real.between_plus_minus_one_incl(int)? {
453			Ok(Self::from(self.real.acos(int)?))
454		} else {
455			// acos(z) = pi/2 + i * ln(i * z + sqrt(1 - z^2))
456			let half_pi = Exact::new(Self::pi(), true).div(Exact::new(Self::from(2), true), int)?;
457			Ok(half_pi
458				.add(
459					self.asin_ln(int)?.mul(&Exact::new(Self::i(), true), int)?,
460					int,
461				)?
462				.value)
463		}
464	}
465
466	pub(crate) fn atan<I: Interrupt>(self, int: &I) -> FResult<Self> {
467		// Real atan is defined for all real numbers
468		if self.imag.is_zero() {
469			Ok(Self::from(self.real.atan(int)?))
470		} else {
471			// i/2 * (ln(-iz+1) - ln(iz+1))
472			let half_i = Exact::new(Self::i(), true).div(Exact::new(Self::from(2), true), int)?;
473			let z1 = Exact::new(self.clone(), true)
474				.mul(&Exact::new(Self::i().neg(), true), int)?
475				.add(Exact::new(Self::from(1), true), int)?;
476			let z2 = Exact::new(self, true)
477				.mul(&Exact::new(Self::i(), true), int)?
478				.add(Exact::new(Self::from(1), true), int)?;
479
480			Ok(half_i
481				.mul(
482					&z1.try_and_then(|z| z.ln(int))?
483						.add(z2.try_and_then(|z| z.ln(int))?.neg(), int)?,
484					int,
485				)?
486				.value)
487		}
488	}
489
490	pub(crate) fn sinh<I: Interrupt>(self, int: &I) -> FResult<Self> {
491		if self.imag.is_zero() {
492			Ok(Self::from(self.real.sinh(int)?))
493		} else {
494			// sinh(a+bi)=sinh(a)cos(b)+icosh(a)sin(b)
495			let sinh = Exact::new(self.real.clone().sinh(int)?, false);
496			let cos = self.imag.clone().cos(int)?;
497			let cosh = Exact::new(self.real.cosh(int)?, false);
498			let sin = self.imag.sin(int)?;
499
500			Ok(Self {
501				real: sinh.mul(cos.re(), int)?.value,
502				imag: cosh.mul(sin.re(), int)?.value,
503			})
504		}
505	}
506
507	pub(crate) fn cosh<I: Interrupt>(self, int: &I) -> FResult<Self> {
508		if self.imag.is_zero() {
509			Ok(Self::from(self.real.cosh(int)?))
510		} else {
511			// cosh(a+bi)=cosh(a)cos(b)+isinh(a)sin(b)
512			let cosh = Exact::new(self.real.clone().cosh(int)?, false);
513			let cos = self.imag.clone().cos(int)?;
514			let sinh = Exact::new(self.real.sinh(int)?, false);
515			let sin = self.imag.sin(int)?;
516
517			Ok(Self {
518				real: cosh.mul(cos.re(), int)?.value,
519				imag: sinh.mul(sin.re(), int)?.value,
520			})
521		}
522	}
523
524	pub(crate) fn tanh<I: Interrupt>(self, int: &I) -> FResult<Self> {
525		if self.imag.is_zero() {
526			Ok(Self::from(self.real.tanh(int)?))
527		} else {
528			// tanh(a+bi)=sinh(a+bi)/cosh(a+bi)
529			Exact::new(self.clone().sinh(int)?, false)
530				.div(Exact::new(self.cosh(int)?, false), int)
531				.map(|x| x.value)
532		}
533	}
534
535	pub(crate) fn asinh<I: Interrupt>(self, int: &I) -> FResult<Self> {
536		// Real asinh is defined for all real numbers
537		if self.imag.is_zero() {
538			Ok(Self::from(self.real.asinh(int)?))
539		} else {
540			// asinh(z)=ln(z+sqrt(z^2+1))
541			let exact = Exact::new(self, true);
542			let half = Exact::new(Self::from(1), true).div(Exact::new(Self::from(2), true), int)?;
543			let sqrt = exact
544				.clone()
545				.mul(&exact, int)?
546				.add(Exact::new(Self::from(1), true), int)?
547				.try_and_then(|x| x.frac_pow(half.value, int))?;
548			sqrt.add(exact, int)?
549				.try_and_then(|x| x.ln(int))
550				.map(|x| x.value)
551		}
552	}
553
554	pub(crate) fn acosh<I: Interrupt>(self, int: &I) -> FResult<Self> {
555		// Real acosh is defined for x >= 1
556		if self.imag.is_zero() && self.real.compare(&1.into(), int)? != Ordering::Less {
557			Ok(Self::from(self.real.acosh(int)?))
558		} else {
559			// acosh(z)=ln(z+sqrt(z^2-1))
560			let exact = Exact::new(self, true);
561			let half = Exact::new(Self::from(1), true).div(Exact::new(Self::from(2), true), int)?;
562			let sqrt = exact
563				.clone()
564				.mul(&exact, int)?
565				.add(Exact::new(Self::from(1), true).neg(), int)?
566				.try_and_then(|x| x.frac_pow(half.value, int))?;
567			sqrt.add(exact, int)?
568				.try_and_then(|x| x.ln(int))
569				.map(|x| x.value)
570		}
571	}
572
573	pub(crate) fn atanh<I: Interrupt>(self, int: &I) -> FResult<Self> {
574		// Real atanh is defined for -1 < x < 1
575		// Undefined for x = 1, -1
576		if self.imag.is_zero() && self.real.between_plus_minus_one_excl(int)? {
577			Ok(Self::from(self.real.atanh(int)?))
578		} else {
579			// atanh(z)=ln(sqrt(-(z-1)/(z-1)))
580			let exact = Exact::new(self, true);
581			let one = Exact::new(Self::from(1), true);
582			let half = Exact::new(Self::from(1), true).div(Exact::new(Self::from(2), true), int)?;
583
584			exact
585				.clone()
586				.add(one.clone(), int)?
587				.neg()
588				.div(exact.add(one.neg(), int)?, int)?
589				.try_and_then(|x| x.frac_pow(half.value, int))?
590				.try_and_then(|z| z.ln(int))
591				.map(|x| x.value)
592		}
593	}
594
595	pub(crate) fn ln<I: Interrupt>(self, int: &I) -> FResult<Exact<Self>> {
596		if self.imag.is_zero() && self.real.is_pos() {
597			Ok(self.real.ln(int)?.apply(Self::from))
598		} else {
599			// ln(z) = ln(|z|) + i * arg(z)
600			let abs = self.clone().abs(int)?;
601			let real = abs.value.ln(int)?.combine(abs.exact);
602			let arg = self.arg(int)?;
603
604			Ok(Exact::new(
605				Self {
606					real: real.value,
607					imag: arg.value,
608				},
609				real.exact && arg.exact,
610			))
611		}
612	}
613
614	pub(crate) fn log<I: Interrupt>(self, base: Self, int: &I) -> FResult<Self> {
615		// log_n(z) = ln(z) / ln(n)
616		let ln = self.ln(int)?;
617		let ln2 = base.ln(int)?;
618		Ok(ln.div(ln2, int)?.value)
619	}
620
621	pub(crate) fn log2<I: Interrupt>(self, int: &I) -> FResult<Self> {
622		if self.imag.is_zero() && self.real.is_pos() {
623			Ok(Self::from(self.real.log2(int)?))
624		} else {
625			self.log(Self::from(2), int)
626		}
627	}
628	pub(crate) fn log10<I: Interrupt>(self, int: &I) -> FResult<Self> {
629		if self.imag.is_zero() && self.real.is_pos() {
630			Ok(Self::from(self.real.log10(int)?))
631		} else {
632			self.log(Self::from(10), int)
633		}
634	}
635
636	pub(crate) fn is_definitely_one(&self) -> bool {
637		self.real.is_definitely_one() && self.imag.is_definitely_zero()
638	}
639
640	pub(crate) fn modulo<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
641		Ok(Self::from(
642			self.expect_real()?.modulo(rhs.expect_real()?, int)?,
643		))
644	}
645
646	pub(crate) fn bitwise<I: Interrupt>(
647		self,
648		rhs: Self,
649		op: crate::ast::BitwiseBop,
650		int: &I,
651	) -> FResult<Self> {
652		Ok(Self::from(self.expect_real()?.bitwise(
653			rhs.expect_real()?,
654			op,
655			int,
656		)?))
657	}
658
659	pub(crate) fn combination<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
660		Ok(Self::from(
661			self.expect_real()?.combination(rhs.expect_real()?, int)?,
662		))
663	}
664
665	pub(crate) fn permutation<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
666		Ok(Self::from(
667			self.expect_real()?.permutation(rhs.expect_real()?, int)?,
668		))
669	}
670}
671
672impl Exact<Complex> {
673	pub(crate) fn add<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
674		let (self_real, self_imag) = self.apply(|x| (x.real, x.imag)).pair();
675		let (rhs_real, rhs_imag) = rhs.apply(|x| (x.real, x.imag)).pair();
676		let real = self_real.add(rhs_real, int)?;
677		let imag = self_imag.add(rhs_imag, int)?;
678		Ok(Self::new(
679			Complex {
680				real: real.value,
681				imag: imag.value,
682			},
683			real.exact && imag.exact,
684		))
685	}
686
687	pub(crate) fn mul<I: Interrupt>(self, rhs: &Self, int: &I) -> FResult<Self> {
688		// (a + bi) * (c + di)
689		//     => ac + bci + adi - bd
690		//     => (ac - bd) + (bc + ad)i
691		let (self_real, self_imag) = self.apply(|x| (x.real, x.imag)).pair();
692		let (rhs_real, rhs_imag) = rhs.clone().apply(|x| (x.real, x.imag)).pair();
693
694		let prod1 = self_real.clone().mul(rhs_real.re(), int)?;
695		let prod2 = self_imag.clone().mul(rhs_imag.re(), int)?;
696		let real_part = prod1.add(-prod2, int)?;
697		let prod3 = self_real.mul(rhs_imag.re(), int)?;
698		let prod4 = self_imag.mul(rhs_real.re(), int)?;
699		let imag_part = prod3.add(prod4, int)?;
700		Ok(Self::new(
701			Complex {
702				real: real_part.value,
703				imag: imag_part.value,
704			},
705			real_part.exact && imag_part.exact,
706		))
707	}
708
709	pub(crate) fn div<I: Interrupt>(self, rhs: Self, int: &I) -> FResult<Self> {
710		// (u + vi) / (x + yi) = (1/(x^2 + y^2)) * ((ux + vy) + (vx - uy)i)
711		let (u, v) = self.apply(|x| (x.real, x.imag)).pair();
712		let (x, y) = rhs.apply(|x| (x.real, x.imag)).pair();
713		// if both numbers are real, use this simplified algorithm
714		if v.exact && v.value.is_zero() && y.exact && y.value.is_zero() {
715			return Ok(u.div(&x, int)?.apply(|real| Complex {
716				real,
717				imag: 0.into(),
718			}));
719		}
720		let prod1 = x.clone().mul(x.re(), int)?;
721		let prod2 = y.clone().mul(y.re(), int)?;
722		let sum = prod1.add(prod2, int)?;
723		let real_part = Exact::new(Real::from(1), true).div(&sum, int)?;
724		let prod3 = u.clone().mul(x.re(), int)?;
725		let prod4 = v.clone().mul(y.re(), int)?;
726		let real2 = prod3.add(prod4, int)?;
727		let prod5 = v.mul(x.re(), int)?;
728		let prod6 = u.mul(y.re(), int)?;
729		let imag2 = prod5.add(-prod6, int)?;
730		let multiplicand = Self::new(
731			Complex {
732				real: real2.value,
733				imag: imag2.value,
734			},
735			real2.exact && imag2.exact,
736		);
737		let result = Self::new(
738			Complex {
739				real: real_part.value,
740				imag: 0.into(),
741			},
742			real_part.exact,
743		)
744		.mul(&multiplicand, int)?;
745		Ok(result)
746	}
747}
748
749impl Neg for Complex {
750	type Output = Self;
751
752	fn neg(self) -> Self {
753		Self {
754			real: -self.real,
755			imag: -self.imag,
756		}
757	}
758}
759
760impl Neg for &Complex {
761	type Output = Complex;
762
763	fn neg(self) -> Complex {
764		-self.clone()
765	}
766}
767
768impl From<u64> for Complex {
769	fn from(i: u64) -> Self {
770		Self {
771			real: i.into(),
772			imag: 0.into(),
773		}
774	}
775}
776
777impl From<Real> for Complex {
778	fn from(i: Real) -> Self {
779		Self {
780			real: i,
781			imag: 0.into(),
782		}
783	}
784}
785
786#[derive(Debug)]
787pub(crate) struct Formatted {
788	first_component: real::Formatted,
789	separator: &'static str,
790	second_component: Option<real::Formatted>,
791	use_parentheses: bool,
792}
793
794impl fmt::Display for Formatted {
795	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796		if self.use_parentheses {
797			write!(f, "(")?;
798		}
799		write!(f, "{}{}", self.first_component, self.separator)?;
800		if let Some(second_component) = &self.second_component {
801			write!(f, "{second_component}")?;
802		}
803		if self.use_parentheses {
804			write!(f, ")")?;
805		}
806		Ok(())
807	}
808}