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 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 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 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 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 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 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 if self.imag.is_zero() && self.real.between_plus_minus_one_incl(int)? {
439 Ok(Self::from(self.real.asin(int)?))
440 } else {
441 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 if self.imag.is_zero() && self.real.between_plus_minus_one_incl(int)? {
453 Ok(Self::from(self.real.acos(int)?))
454 } else {
455 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 if self.imag.is_zero() {
469 Ok(Self::from(self.real.atan(int)?))
470 } else {
471 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 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 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 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 if self.imag.is_zero() {
538 Ok(Self::from(self.real.asinh(int)?))
539 } else {
540 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 if self.imag.is_zero() && self.real.compare(&1.into(), int)? != Ordering::Less {
557 Ok(Self::from(self.real.acosh(int)?))
558 } else {
559 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 if self.imag.is_zero() && self.real.between_plus_minus_one_excl(int)? {
577 Ok(Self::from(self.real.atanh(int)?))
578 } else {
579 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 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 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 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 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 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}