1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::{
9 core::{errors::capture_backtrace, policies::StrictFinitePolicy},
10 functions::FunctionErrors,
11 kernels::{RawComplexTrait, RawRealTrait, RawScalarTrait},
12};
13use duplicate::duplicate_item;
14use num::{Complex, Zero};
15use num_traits::int::PrimInt;
16use std::backtrace::Backtrace;
17use thiserror::Error;
18use try_create::ValidationPolicy;
19
20pub trait IntegerExponent: PrimInt {}
23
24impl IntegerExponent for i8 {}
25impl IntegerExponent for u8 {}
26impl IntegerExponent for i16 {}
27impl IntegerExponent for u16 {}
28impl IntegerExponent for i32 {}
29impl IntegerExponent for u32 {}
30impl IntegerExponent for i64 {}
31impl IntegerExponent for u64 {}
32impl IntegerExponent for i128 {}
33impl IntegerExponent for u128 {}
34impl IntegerExponent for isize {}
35impl IntegerExponent for usize {}
36#[derive(Debug, Error)]
46pub enum PowRealBaseRealExponentInputErrors<RawReal: RawRealTrait> {
47 #[error("detected a negative base ({base}) with a real exponent ({exponent}) !")]
51 NegativeBase {
52 base: RawReal,
54
55 exponent: RawReal,
57
58 backtrace: Backtrace,
60 },
61
62 #[error("the base is invalid!")]
67 InvalidBase {
68 #[source]
71 #[backtrace]
72 source: <RawReal as RawScalarTrait>::ValidationErrors,
73 },
74
75 #[error("the exponent is invalid!")]
80 InvalidExponent {
81 #[source]
84 #[backtrace]
85 source: <RawReal as RawScalarTrait>::ValidationErrors,
86 },
87
88 #[error("the base and the exponent are invalid!")]
92 InvalidBaseAndExponent {
93 error_base: <RawReal as RawScalarTrait>::ValidationErrors,
95
96 error_exponent: <RawReal as RawScalarTrait>::ValidationErrors,
98
99 #[backtrace]
101 backtrace: Backtrace,
102 },
103}
104#[derive(Debug, Error)]
114pub enum PowComplexBaseRealExponentInputErrors<RawComplex: RawComplexTrait> {
115 #[error("the input complex base is invalid according to validation policy")]
120 InvalidBase {
121 #[source]
124 #[backtrace]
125 source: <RawComplex as RawScalarTrait>::ValidationErrors,
126 },
127
128 #[error("the input real exponent is invalid according to validation policy")]
133 InvalidExponent {
134 #[source]
137 #[backtrace]
138 source: <RawComplex::RawReal as RawScalarTrait>::ValidationErrors,
139 },
140
141 #[error(
146 "the input complex base and the real exponent is invalid according to validation policy"
147 )]
148 InvalidBaseAndExponent {
149 error_base: <RawComplex as RawScalarTrait>::ValidationErrors,
151
152 error_exponent: <RawComplex::RawReal as RawScalarTrait>::ValidationErrors,
154
155 #[backtrace]
157 backtrace: Backtrace,
158 },
159
160 #[error("the base is zero and the exponent (={exponent}) is negative!")]
163 ZeroBaseNegativeExponent {
164 exponent: RawComplex::RawReal,
166
167 backtrace: Backtrace,
169 },
170}
171#[derive(Debug, Error)]
181pub enum PowIntExponentInputErrors<RawScalar: RawScalarTrait, ExponentType: IntegerExponent> {
182 #[error("the input base is invalid according to validation policy")]
187 InvalidBase {
188 #[source]
191 #[backtrace]
192 source: <RawScalar as RawScalarTrait>::ValidationErrors,
193 },
194
195 #[error("detected a zero base with a negative integer exponent ({exponent:?})!")]
198 ZeroBaseNegativeExponent {
199 exponent: ExponentType,
201
202 backtrace: Backtrace,
204 },
205 }
210#[derive(Debug, Error)]
222pub enum PowRealBaseRealExponentErrors<RawReal: RawRealTrait> {
223 #[error("the input value is invalid!")]
225 Input {
226 #[from]
228 source: PowRealBaseRealExponentInputErrors<RawReal>,
229 },
230
231 #[error("the output value is invalid!")]
233 Output {
234 #[source]
236 #[backtrace]
237 source: <RawReal as RawScalarTrait>::ValidationErrors,
238 },
239}
240#[derive(Debug, Error)]
251pub enum PowComplexBaseRealExponentErrors<RawComplex: RawComplexTrait> {
252 #[error("the input value is invalid!")]
254 Input {
255 #[from]
257 source: PowComplexBaseRealExponentInputErrors<RawComplex>,
258 },
259
260 #[error("the output value is invalid!")]
262 Output {
263 #[source]
265 #[backtrace]
266 source: <RawComplex as RawScalarTrait>::ValidationErrors,
267 },
268}
269pub type PowIntExponentErrors<RawScalar, ExponentType> = FunctionErrors<
281 PowIntExponentInputErrors<RawScalar, ExponentType>,
282 <RawScalar as RawScalarTrait>::ValidationErrors,
283>;
284pub trait Pow<ExponentType>: Sized {
299 type Error: std::error::Error;
302
303 #[must_use = "this `Result` may contain an error that should be handled"]
315 fn try_pow(self, exponent: ExponentType) -> Result<Self, Self::Error>;
316
317 fn pow(self, exponent: ExponentType) -> Self;
350}
351
352impl Pow<&f64> for f64 {
353 type Error = PowRealBaseRealExponentErrors<f64>;
354
355 #[inline(always)]
356 fn try_pow(self, exponent: &f64) -> Result<Self, Self::Error> {
357 let validation_base = StrictFinitePolicy::<f64, 53>::validate(self);
358 let validation_exponent = StrictFinitePolicy::<f64, 53>::validate_ref(exponent);
359 match (validation_base, validation_exponent) {
360 (Ok(base), Ok(())) => {
361 if base < 0.0 {
362 Err(PowRealBaseRealExponentInputErrors::NegativeBase {
363 base,
364 exponent: *exponent,
365 backtrace: capture_backtrace(),
366 }
367 .into())
368 } else {
369 let result = base.powf(*exponent);
370 StrictFinitePolicy::<f64, 53>::validate(result)
371 .map_err(|e| PowRealBaseRealExponentErrors::Output { source: e })
372 }
373 }
374 (Ok(_), Err(error_exponent)) => {
375 Err(PowRealBaseRealExponentInputErrors::InvalidExponent {
376 source: error_exponent,
377 }
378 .into())
379 }
380 (Err(error_base), Ok(_)) => {
381 Err(PowRealBaseRealExponentInputErrors::InvalidBase { source: error_base }.into())
382 }
383 (Err(error_base), Err(error_exponent)) => {
384 Err(PowRealBaseRealExponentInputErrors::InvalidBaseAndExponent {
385 error_base,
386 error_exponent,
387 backtrace: capture_backtrace(),
388 }
389 .into())
390 }
391 }
392 }
393
394 #[inline(always)]
395 fn pow(self, exponent: &f64) -> Self {
397 #[cfg(debug_assertions)]
398 {
399 self.try_pow(exponent).unwrap()
400 }
401 #[cfg(not(debug_assertions))]
402 {
403 self.powf(*exponent)
404 }
405 }
406}
407
408impl Pow<&f64> for Complex<f64> {
409 type Error = PowComplexBaseRealExponentErrors<Self>;
410
411 #[inline(always)]
412 fn try_pow(self, exponent: &f64) -> Result<Self, Self::Error> {
413 let validation_base = StrictFinitePolicy::<Complex<f64>, 53>::validate(self);
414 let validation_exponent = StrictFinitePolicy::<f64, 53>::validate_ref(exponent);
415 match (validation_base, validation_exponent) {
416 (Ok(base), Ok(())) => {
417 if Zero::is_zero(&base) {
418 if *exponent < 0.0 {
419 Err(
420 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent {
421 exponent: *exponent,
422 backtrace: capture_backtrace(),
423 }
424 .into(),
425 )
426 } else if *exponent == 0.0 {
427 Ok(Complex::new(1.0, 0.0))
428 } else {
429 Ok(Complex::new(0.0, 0.0))
430 }
431 } else {
432 let result = base.powf(*exponent);
433 StrictFinitePolicy::<Complex<f64>, 53>::validate(result)
434 .map_err(|e| PowComplexBaseRealExponentErrors::Output { source: e })
435 }
436 }
437 (Ok(_), Err(error_exponent)) => {
438 Err(PowComplexBaseRealExponentInputErrors::InvalidExponent {
439 source: error_exponent,
440 }
441 .into())
442 }
443 (Err(error_base), Ok(_)) => {
444 Err(
445 PowComplexBaseRealExponentInputErrors::InvalidBase { source: error_base }
446 .into(),
447 )
448 }
449 (Err(error_base), Err(error_exponent)) => Err(
450 PowComplexBaseRealExponentInputErrors::InvalidBaseAndExponent {
451 error_base,
452 error_exponent,
453 backtrace: capture_backtrace(),
454 }
455 .into(),
456 ),
457 }
458 }
459
460 #[inline(always)]
461 fn pow(self, exponent: &f64) -> Self {
463 #[cfg(debug_assertions)]
464 {
465 self.try_pow(exponent)
466 .expect("Error raised by Pow::try_pow() in the function Pow::pow() (debug mode)")
467 }
468 #[cfg(not(debug_assertions))]
469 {
470 self.powf(*exponent)
471 }
472 }
473}
474
475#[duplicate_item(
476 exponent_type exponent_func;
477 [i8] [exponent.into()];
478 [i16] [exponent.into()];
479 [i32] [exponent];
480 [i64] [exponent.try_into().unwrap()];
481 [i128] [exponent.try_into().unwrap()];
482 [isize] [exponent.try_into().unwrap()];
483)]
484impl Pow<exponent_type> for f64 {
485 type Error = PowIntExponentErrors<f64, exponent_type>;
486
487 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
488 StrictFinitePolicy::<f64, 53>::validate(self)
489 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
490 .and_then(|base| {
491 if base == 0. && exponent < 0 {
492 Err(PowIntExponentInputErrors::ZeroBaseNegativeExponent {
493 exponent,
494 backtrace: capture_backtrace(),
495 }
496 .into())
497 } else {
498 let res = base.powi(exponent_func);
499 StrictFinitePolicy::<f64, 53>::validate(res)
500 .map_err(|e| Self::Error::Output { source: e })
501 }
502 })
503 }
504
505 #[inline(always)]
506 fn pow(self, exponent: exponent_type) -> Self {
508 #[cfg(debug_assertions)]
509 {
510 self.try_pow(exponent).unwrap()
511 }
512 #[cfg(not(debug_assertions))]
513 {
514 self.powi(exponent_func)
515 }
516 }
517}
518
519#[duplicate_item(
520 exponent_type exponent_func;
521 [u8] [exponent.into()];
522 [u16] [exponent.into()];
523 [u32] [exponent.try_into().unwrap()];
524 [u64] [exponent.try_into().unwrap()];
525 [u128] [exponent.try_into().unwrap()];
526 [usize] [exponent.try_into().unwrap()];
527)]
528impl Pow<exponent_type> for f64 {
529 type Error = PowIntExponentErrors<f64, exponent_type>;
530
531 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
532 StrictFinitePolicy::<f64, 53>::validate(self)
533 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
534 .and_then(|base| {
535 let res = base.powi(exponent_func);
536 StrictFinitePolicy::<f64, 53>::validate(res)
537 .map_err(|e| Self::Error::Output { source: e })
538 })
539 }
540
541 #[inline(always)]
542 fn pow(self, exponent: exponent_type) -> Self {
544 #[cfg(debug_assertions)]
545 {
546 self.try_pow(exponent).unwrap()
547 }
548 #[cfg(not(debug_assertions))]
549 {
550 self.powi(exponent_func)
551 }
552 }
553}
554
555#[duplicate_item(
556 exponent_type func_name exponent_func;
557 [i8] [powi] [exponent.into()];
558 [i16] [powi] [exponent.into()];
559 [i32] [powi] [exponent];
560 [i64] [powi] [exponent.try_into().unwrap()];
561 [i128] [powi] [exponent.try_into().unwrap()];
562 [isize] [powi] [exponent.try_into().unwrap()];
563)]
564impl Pow<exponent_type> for Complex<f64> {
565 type Error = PowIntExponentErrors<Complex<f64>, exponent_type>;
566
567 #[inline(always)]
568 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
569 StrictFinitePolicy::<Self, 53>::validate(self)
570 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
571 .and_then(|base| {
572 if Zero::is_zero(&base) && exponent < 0 {
573 Err(PowIntExponentInputErrors::ZeroBaseNegativeExponent {
574 exponent,
575 backtrace: capture_backtrace(),
576 }
577 .into())
578 } else {
579 StrictFinitePolicy::<Self, 53>::validate(base.func_name(exponent_func))
580 .map_err(|e| Self::Error::Output { source: e })
581 }
582 })
583 }
584
585 #[inline(always)]
586 fn pow(self, exponent: exponent_type) -> Self {
588 #[cfg(debug_assertions)]
589 {
590 self.try_pow(exponent).unwrap()
591 }
592 #[cfg(not(debug_assertions))]
593 {
594 self.func_name(exponent_func)
595 }
596 }
597}
598
599#[duplicate_item(
600 exponent_type func_name exponent_func;
601 [u8] [powu] [exponent.into()];
602 [u16] [powu] [exponent.into()];
603 [u32] [powu] [exponent];
604 [u64] [powu] [exponent.try_into().unwrap()];
605 [u128] [powu] [exponent.try_into().unwrap()];
606 [usize] [powu] [exponent.try_into().unwrap()];
607)]
608impl Pow<exponent_type> for Complex<f64> {
609 type Error = PowIntExponentErrors<Complex<f64>, exponent_type>;
610
611 #[inline(always)]
612 fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
613 StrictFinitePolicy::<Self, 53>::validate(self)
614 .map_err(|e| PowIntExponentInputErrors::InvalidBase { source: e }.into())
615 .and_then(|base| {
616 StrictFinitePolicy::<Self, 53>::validate(base.func_name(exponent_func))
617 .map_err(|e| Self::Error::Output { source: e })
618 })
619 }
620
621 #[inline(always)]
622 fn pow(self, exponent: exponent_type) -> Self {
624 #[cfg(debug_assertions)]
625 {
626 self.try_pow(exponent).unwrap()
627 }
628 #[cfg(not(debug_assertions))]
629 {
630 self.func_name(exponent_func)
631 }
632 }
633}
634pub trait PowIntExponent:
639 Pow<i8, Error = PowIntExponentErrors<Self::RawType, i8>>
640 + Pow<u8, Error = PowIntExponentErrors<Self::RawType, u8>>
641 + Pow<i16, Error = PowIntExponentErrors<Self::RawType, i16>>
642 + Pow<u16, Error = PowIntExponentErrors<Self::RawType, u16>>
643 + Pow<i32, Error = PowIntExponentErrors<Self::RawType, i32>>
644 + Pow<u32, Error = PowIntExponentErrors<Self::RawType, u32>>
645 + Pow<i64, Error = PowIntExponentErrors<Self::RawType, i64>>
646 + Pow<u64, Error = PowIntExponentErrors<Self::RawType, u64>>
647 + Pow<i128, Error = PowIntExponentErrors<Self::RawType, i128>>
648 + Pow<u128, Error = PowIntExponentErrors<Self::RawType, u128>>
649 + Pow<isize, Error = PowIntExponentErrors<Self::RawType, isize>>
650 + Pow<usize, Error = PowIntExponentErrors<Self::RawType, usize>>
651{
652 type RawType: RawScalarTrait;
656}
657
658impl PowIntExponent for f64 {
659 type RawType = f64;
660}
661
662impl PowIntExponent for Complex<f64> {
663 type RawType = Complex<f64>;
664}
665
666#[cfg(test)]
670mod tests {
671 use super::*;
672 use crate::{
673 RealScalar,
674 core::errors::{ErrorsValidationRawComplex, ErrorsValidationRawReal},
675 functions::{
676 Pow, PowIntExponentErrors, PowIntExponentInputErrors,
677 PowRealBaseRealExponentInputErrors,
678 },
679 };
680 use num::Complex;
681
682 #[cfg(feature = "rug")]
683 use crate::backends::rug::validated::{ComplexRugStrictFinite, RealRugStrictFinite};
684
685 #[cfg(feature = "rug")]
686 use try_create::TryNew;
687
688 mod pow_u32_exponent {
689 use super::*;
690
691 mod real_base {
692 use super::*;
693
694 fn pow_generic_real_u32_valid<RealType: RealScalar>() {
695 let base = RealType::try_from_f64(2.0).unwrap();
696 let exponent = 3u32;
697 let expected_result = RealType::try_from_f64(8.0).unwrap();
698 assert_eq!(Pow::pow(base.clone(), exponent), expected_result);
699 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
700 }
701
702 #[test]
703 fn test_pow_generic_real_u32_valid() {
704 pow_generic_real_u32_valid::<f64>();
705 }
706
707 #[test]
708 fn test_f64_pow_u32_valid() {
709 let base = 2.0;
710 let exponent = 3u32;
711 let expected_result = 8.0;
712 assert_eq!(Pow::pow(base, exponent), expected_result);
713 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
714 }
715
716 #[test]
717 fn test_f64_pow_u32_zero_exponent() {
718 let base = 2.0;
719 let exponent = 0u32;
720 let expected_result = 1.0;
721 assert_eq!(Pow::pow(base, exponent), expected_result);
722 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
723 }
724
725 #[test]
726 fn test_f64_pow_u32_one_exponent() {
727 let base = 2.0;
728 let exponent = 1u32;
729 let expected_result = 2.0;
730 assert_eq!(Pow::pow(base, exponent), expected_result);
731 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
732 }
733
734 #[test]
735 fn test_f64_pow_u32_zero_base() {
736 let base = 0.0;
737 let exponent = 3u32;
738 let expected_result = 0.0;
739 assert_eq!(Pow::pow(base, exponent), expected_result);
740 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
741 }
742
743 #[test]
744 fn test_f64_pow_u32_nan_base() {
745 let base = f64::NAN;
746 let exponent = 3u32;
747 let result = base.try_pow(exponent);
748 assert!(result.is_err());
749 }
750
751 #[test]
752 fn test_f64_pow_u32_infinity_base() {
753 let base = f64::INFINITY;
754 let exponent = 3u32;
755 let result = base.try_pow(exponent);
756 assert!(result.is_err());
757 }
758 }
759
760 mod complex_base {
761 use super::*;
762
763 #[test]
764 fn test_complex_f64_pow_u32_valid() {
765 let base = Complex::new(2.0, 3.0);
766 let exponent = 2u32;
767 let expected_result = Complex::new(-5.0, 12.0);
768 assert_eq!(Pow::pow(base, exponent), expected_result);
769 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
770 }
771
772 #[test]
773 fn test_complex_f64_pow_u32_zero_exponent() {
774 let base = Complex::new(2.0, 3.0);
775 let exponent = 0u32;
776 let expected_result = Complex::new(1.0, 0.0);
777 assert_eq!(Pow::pow(base, exponent), expected_result);
778 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
779 }
780
781 #[test]
782 fn test_complex_f64_pow_u32_one_exponent() {
783 let base = Complex::new(2.0, 3.0);
784 let exponent = 1u32;
785 let expected_result = Complex::new(2.0, 3.0);
786 assert_eq!(Pow::pow(base, exponent), expected_result);
787 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
788 }
789
790 #[test]
791 fn test_complex_f64_pow_u32_zero_base() {
792 let base = Complex::new(0.0, 0.0);
793 let exponent = 3u32;
794 let expected_result = Complex::new(0.0, 0.0);
795 assert_eq!(Pow::pow(base, exponent), expected_result);
796 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
797 }
798
799 #[test]
800 fn test_complex_f64_pow_u32_nan_base() {
801 let base = Complex::new(f64::NAN, 0.0);
802 let exponent = 3u32;
803 let result = base.try_pow(exponent);
804 assert!(result.is_err());
805
806 let base = Complex::new(0.0, f64::NAN);
807 let result = base.try_pow(exponent);
808 assert!(result.is_err());
809 }
810
811 #[test]
812 fn test_complex_f64_pow_u32_infinity_base() {
813 let base = Complex::new(f64::INFINITY, 0.0);
814 let exponent = 3u32;
815 let result = base.try_pow(exponent);
816 assert!(result.is_err());
817
818 let base = Complex::new(0.0, f64::INFINITY);
819 let result = base.try_pow(exponent);
820 assert!(result.is_err());
821 }
822 }
823 }
824
825 mod pow_i32_exponent {
826 use super::*;
827
828 mod native64 {
829 use super::*;
830
831 mod real_base {
832 use super::*;
833
834 #[test]
835 fn test_f64_pow_valid() {
836 let base = 2.0;
837 let exponent = 3i32;
838 let expected_result = 8.0;
839 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
840 assert_eq!(<f64 as Pow<i32>>::pow(base, exponent), expected_result);
841 }
842
843 #[test]
844 fn test_f64_pow_zero_exponent() {
845 let base = 2.0;
846 let exponent = 0i32;
847 let expected_result = 1.0;
848 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
849 }
850
851 #[test]
852 fn test_f64_pow_negative_exponent() {
853 let base = 2.0;
854 let exponent = -3i32;
855 let expected_result = 0.125;
856 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
857 }
858
859 #[test]
860 fn test_f64_pow_zero_base() {
861 let base = 0.0;
862 let exponent = 3i32;
863 let expected_result = 0.0;
864 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
865 }
866
867 #[test]
868 fn test_f64_pow_zero_base_zero_exponent() {
869 let base = 0.0;
870 let exponent = 0i32;
871 let expected_result = 1.0;
872 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
873 }
874
875 #[test]
876 fn test_f64_pow_zero_base_negative_exponent() {
877 let base = 0.0;
878 let err = base.try_pow(-1i32).unwrap_err();
879 assert!(matches!(
880 err,
881 PowIntExponentErrors::Input {
882 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent {
883 exponent: -1,
884 ..
885 }
886 }
887 ));
888 }
889
890 #[test]
891 fn test_f64_pow_negative_base_positive_exponent() {
892 let base = -2.0;
893 let exponent = 3i32;
894 let expected_result = -8.0;
895 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
896 }
897
898 #[test]
899 fn test_f64_pow_negative_base_negative_exponent() {
900 let base = -2.0;
901 let exponent = -3i32;
902 let expected_result = -0.125;
903 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
904 }
905 }
906
907 mod complex_base {
908 use super::*;
909
910 #[test]
911 fn test_complex_f64_pow_valid() {
912 let base = Complex::new(2.0, 3.0);
913 let exponent = 2i32;
914 let expected_result = Complex::new(-5.0, 12.0);
915 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
916 assert_eq!(
917 <Complex<f64> as Pow<i32>>::pow(base, exponent),
918 expected_result
919 );
920 }
921
922 #[test]
923 fn test_complex_f64_pow_zero_exponent() {
924 let base = Complex::new(2.0, 3.0);
925 let exponent = 0i32;
926 let expected_result = Complex::new(1.0, 0.0);
927 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
928 }
929
930 #[test]
931 fn test_complex_f64_pow_negative_exponent() {
932 let base = Complex::new(2.0, 3.0);
933 let exponent = -2i32;
934 let expected_result = Complex::new(-0.029585798816568053, -0.07100591715976332);
935 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
936 }
937
938 #[test]
939 fn test_complex_f64_pow_zero_base() {
940 let base = Complex::new(0.0, 0.0);
941 let exponent = 3i32;
942 let expected_result = Complex::new(0.0, 0.0);
943 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
944 }
945
946 #[test]
947 fn test_complex_f64_pow_zero_base_zero_exponent() {
948 let base = Complex::new(0.0, 0.0);
949 let exponent = 0i32;
950 let expected_result = Complex::new(1.0, 0.0);
951 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
952 }
953
954 #[test]
955 fn test_complex_f64_pow_zero_base_negative_exponent() {
956 let base = Complex::new(0.0, 0.0);
957 let err = base.try_pow(-1i32).unwrap_err();
958 assert!(matches!(
959 err,
960 PowIntExponentErrors::Input {
961 source: PowIntExponentInputErrors::ZeroBaseNegativeExponent {
962 exponent: -1,
963 ..
964 }
965 }
966 ));
967 }
968
969 #[test]
970 fn test_complex_f64_pow_negative_base_positive_exponent() {
971 let base = Complex::new(-2.0, -3.0);
972 let exponent = 3i32;
973 let expected_result = Complex::new(46.0, -9.0);
974 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
975 }
976
977 #[test]
978 fn test_complex_f64_pow_negative_base_negative_exponent() {
979 let base = Complex::new(-2.0, -3.0);
980 let exponent = -3i32;
981 let expected_result = Complex::new(0.02093764223941739, 0.004096495220755574);
982 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
983 }
984 }
985 }
986
987 #[cfg(feature = "rug")]
988 mod rug53 {
989 use super::*;
990 use crate::backends::rug::validated::{ComplexRugStrictFinite, RealRugStrictFinite};
991 use rug::Float;
992
993 mod real {
994 use super::*;
995
996 #[test]
997 fn test_rug_float_pow_valid() {
998 let base =
999 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1000 let exponent = 3;
1001 let expected_result =
1002 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 8.0)).unwrap();
1003 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1004 }
1005
1006 #[test]
1007 fn test_rug_float_pow_zero_exponent() {
1008 let base =
1009 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1010 let exponent = 0;
1011 let expected_result =
1012 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1013 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1014 }
1015
1016 #[test]
1017 fn test_rug_float_pow_negative_exponent() {
1018 let base =
1019 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1020 let exponent = -3;
1021 let expected_result =
1022 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.125)).unwrap();
1023 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1024 }
1025
1026 #[test]
1027 fn test_rug_float_pow_zero_base() {
1028 let base =
1029 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1030 let exponent = 3;
1031 let expected_result =
1032 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1033 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1034 }
1035
1036 #[test]
1037 fn test_rug_float_pow_zero_base_zero_exponent() {
1038 let base =
1039 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1040 let exponent = 0;
1041 let expected_result =
1042 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1043 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1044 }
1045
1046 #[test]
1047 fn test_rug_float_pow_negative_base_positive_exponent() {
1048 let base =
1049 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1050 let exponent = 3;
1051 let expected_result =
1052 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -8.0)).unwrap();
1053 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1054 }
1055
1056 #[test]
1057 fn test_rug_float_pow_negative_base_negative_exponent() {
1058 let base =
1059 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1060 let exponent = -3;
1061 let expected_result =
1062 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -0.125)).unwrap();
1063 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1064 }
1065 }
1066
1067 mod complex {
1068 use super::*;
1069 use rug::Complex;
1070
1071 #[test]
1072 fn test_complex_rug_float_pow_valid() {
1073 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1074 53,
1075 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1076 ))
1077 .unwrap();
1078 let exponent = 2;
1079 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1080 53,
1081 (Float::with_val(53, -5.0), Float::with_val(53, 12.0)),
1082 ))
1083 .unwrap();
1084 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1085 }
1086
1087 #[test]
1088 fn test_complex_rug_float_pow_zero_exponent() {
1089 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1090 53,
1091 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1092 ))
1093 .unwrap();
1094 let exponent = 0;
1095 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1096 53,
1097 (Float::with_val(53, 1.0), Float::with_val(53, 0.0)),
1098 ))
1099 .unwrap();
1100 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1101 }
1102
1103 #[test]
1104 fn test_complex_rug_float_pow_negative_exponent() {
1105 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1106 53,
1107 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1108 ))
1109 .unwrap();
1110 let exponent = -2;
1111 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1112 53,
1113 (
1114 Float::with_val(53, -2.9585798816568046e-2),
1115 Float::with_val(53, -7.100591715976332e-2),
1116 ),
1117 ))
1118 .unwrap();
1119 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1120 }
1121
1122 #[test]
1123 fn test_complex_rug_float_pow_zero_base() {
1124 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1125 53,
1126 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1127 ))
1128 .unwrap();
1129 let exponent = 3;
1130 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1131 53,
1132 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1133 ))
1134 .unwrap();
1135 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1136 }
1137
1138 #[test]
1139 fn test_complex_rug_float_pow_zero_base_zero_exponent() {
1140 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1141 53,
1142 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1143 ))
1144 .unwrap();
1145 let exponent = 0;
1146 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1147 53,
1148 (Float::with_val(53, 1.0), Float::with_val(53, 0.0)),
1149 ))
1150 .unwrap();
1151 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1152 }
1153
1154 #[test]
1155 fn test_complex_rug_float_pow_negative_base_positive_exponent() {
1156 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1157 53,
1158 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1159 ))
1160 .unwrap();
1161 let exponent = 3;
1162 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1163 53,
1164 (Float::with_val(53, 46.0), Float::with_val(53, -9.0)),
1165 ))
1166 .unwrap();
1167 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1168 }
1169
1170 #[test]
1171 fn test_complex_rug_float_pow_negative_base_negative_exponent() {
1172 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1173 53,
1174 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1175 ))
1176 .unwrap();
1177 let exponent = -3;
1178 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1179 53,
1180 (
1181 Float::with_val(53, 2.0937642239417388e-2),
1182 Float::with_val(53, 4.096495220755576e-3),
1183 ),
1184 ))
1185 .unwrap();
1186 assert_eq!(base.try_pow(exponent).unwrap(), expected_result);
1187 }
1188 }
1189 }
1190 }
1191
1192 mod pow_real_exponent {
1193 use super::*;
1194
1195 mod native64 {
1196 use super::*;
1197
1198 mod real_base {
1199 use super::*;
1200 use core::f64;
1201
1202 #[test]
1203 fn test_f64_pow_f64_valid() {
1204 let base = 2.0;
1205 let exponent = 3.0;
1206 let expected_result = 8.0;
1207 assert_eq!(Pow::pow(base, &exponent), expected_result);
1208 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1209 }
1210
1211 #[test]
1212 fn test_f64_pow_f64_zero_exponent() {
1213 let base = 2.0;
1214 let exponent = 0.0;
1215 let expected_result = 1.0;
1216 assert_eq!(Pow::pow(base, &exponent), expected_result);
1217 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1218 }
1219
1220 #[test]
1221 fn test_f64_pow_f64_invalid_exponent() {
1222 let base = 2.0;
1223 let err = base.try_pow(&f64::NAN).unwrap_err();
1224 assert!(matches!(
1225 err,
1226 PowRealBaseRealExponentErrors::Input {
1227 source: PowRealBaseRealExponentInputErrors::InvalidExponent {
1228 source: ErrorsValidationRawReal::IsNaN { .. }
1229 }
1230 }
1231 ))
1232 }
1233
1234 #[test]
1235 fn test_f64_pow_f64_invalid_base_invalid_exponent() {
1236 let err = (f64::INFINITY).try_pow(&f64::NAN).unwrap_err();
1237 assert!(matches!(
1238 err,
1239 PowRealBaseRealExponentErrors::Input {
1240 source: PowRealBaseRealExponentInputErrors::InvalidBaseAndExponent {
1241 error_base: ErrorsValidationRawReal::IsPosInfinity { .. },
1242 error_exponent: ErrorsValidationRawReal::IsNaN { .. },
1243 ..
1244 }
1245 }
1246 ))
1247 }
1248
1249 #[test]
1250 fn test_f64_pow_f64_one_exponent() {
1251 let base = 2.0;
1252 let exponent = 1.0;
1253 let expected_result = 2.0;
1254 assert_eq!(Pow::pow(base, &exponent), expected_result);
1255 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1256 }
1257
1258 #[test]
1259 fn test_f64_pow_f64_zero_base() {
1260 let base = 0.0;
1261 let exponent = 3.0;
1262 let expected_result = 0.0;
1263 assert_eq!(Pow::pow(base, &exponent), expected_result);
1264 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1265 }
1266
1267 #[test]
1268 fn test_f64_pow_f64_nan_base() {
1269 let base = f64::NAN;
1270 let exponent = 3.0;
1271 let result = base.try_pow(&exponent);
1272 assert!(result.is_err());
1273 }
1274
1275 #[test]
1276 fn test_f64_pow_f64_infinity_base() {
1277 let base = f64::INFINITY;
1278 let exponent = 3.0;
1279 let result = base.try_pow(&exponent);
1280 assert!(matches!(
1281 result,
1282 Err(PowRealBaseRealExponentErrors::Input { .. })
1283 ));
1284 }
1285
1286 #[test]
1287 fn test_f64_pow_f64_negative_exponent() {
1288 let base = 2.0;
1289 let exponent = -2.0;
1290 let expected_result = 0.25;
1291 assert_eq!(Pow::pow(base, &exponent), expected_result);
1292 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1293 }
1294
1295 #[test]
1296 fn test_f64_pow_f64_negative_base_positive_exponent() {
1297 let base = -2.0;
1298 let exponent = 3.0;
1299 let result = base.try_pow(&exponent);
1300 assert!(matches!(
1301 result,
1302 Err(PowRealBaseRealExponentErrors::Input { .. })
1303 ));
1304 }
1305
1306 #[test]
1307 fn test_f64_pow_f64_negative_base_negative_exponent() {
1308 let base = -2.0;
1309 let exponent = -3.0;
1310 let result = base.try_pow(&exponent);
1311 assert!(result.is_err());
1312 }
1313 }
1314
1315 mod complex_base {
1316 use super::*;
1317
1318 #[test]
1319 fn test_complex_f64_pow_ok_base_ok_exponent() {
1320 let base = Complex::new(2.0, 3.0);
1321 let exponent = 2.0;
1322 let expected_result = Complex::new(-4.999999999999999, 11.999999999999998);
1323 assert_eq!(Pow::pow(base, &exponent), expected_result);
1324 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1325 }
1326
1327 #[test]
1328 fn test_complex_f64_pow_ok_base_zero_exponent() {
1329 let base = Complex::new(2.0, 3.0);
1330 let exponent = 0.0;
1331 let expected_result = Complex::new(1.0, 0.0);
1332 assert_eq!(Pow::pow(base, &exponent), expected_result);
1333 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1334 }
1335
1336 #[test]
1337 fn test_complex_f64_pow_zero_base_zero_exponent() {
1338 let base = Complex::new(0.0, 0.0);
1339 let exponent = 0.0;
1340 let expected_result = Complex::new(1.0, 0.0);
1341 assert_eq!(Pow::pow(base, &exponent), expected_result);
1342 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1343 }
1344
1345 #[test]
1346 fn test_complex_f64_pow_zero_base_negative_exponent() {
1347 let base = Complex::new(0.0, 0.0);
1348 let exponent = -1.0;
1349 let err = base.try_pow(&exponent).unwrap_err();
1350 assert!(matches!(
1351 err,
1352 PowComplexBaseRealExponentErrors::Input {
1353 source:
1354 PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent {
1355 exponent: -1.,
1356 ..
1357 }
1358 }
1359 ));
1360 }
1361
1362 #[test]
1363 fn test_complex_f64_pow_ok_base_nan_exponent() {
1364 let base = Complex::new(0.0, 0.0);
1365 let exponent = f64::NAN;
1366 let err = base.try_pow(&exponent).unwrap_err();
1367 assert!(matches!(
1368 err,
1369 PowComplexBaseRealExponentErrors::Input {
1370 source: PowComplexBaseRealExponentInputErrors::InvalidExponent {
1371 source: ErrorsValidationRawReal::IsNaN { .. }
1372 }
1373 }
1374 ));
1375 }
1376
1377 #[test]
1378 fn test_complex_f64_pow_infinity_base_nan_exponent() {
1379 let base = Complex::new(f64::INFINITY, 0.0);
1380 let exponent = f64::NAN;
1381 let err = base.try_pow(&exponent).unwrap_err();
1382 assert!(matches!(
1383 err,
1384 PowComplexBaseRealExponentErrors::Input {
1385 source: PowComplexBaseRealExponentInputErrors::InvalidBaseAndExponent {
1386 error_base: ErrorsValidationRawComplex::InvalidRealPart {
1387 source: ErrorsValidationRawReal::IsPosInfinity { .. }
1388 },
1389 error_exponent: ErrorsValidationRawReal::IsNaN { .. },
1390 ..
1391 }
1392 }
1393 ));
1394 }
1395
1396 #[test]
1397 fn test_complex_f64_pow_ok_base_one_exponent() {
1398 let base = Complex::new(2.0, 3.0);
1399 let exponent = 1.0;
1400 let expected_result = Complex::new(2.0, 3.0);
1401 assert_eq!(Pow::pow(base, &exponent), expected_result);
1402 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1403 }
1404
1405 #[test]
1406 fn test_complex_f64_pow_zero_base_ok_exponent() {
1407 let base = Complex::new(0.0, 0.0);
1408 let exponent = 3.0;
1409 let expected_result = Complex::new(0.0, 0.0);
1410 assert_eq!(Pow::pow(base, &exponent), expected_result);
1411 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1412 }
1413
1414 #[test]
1415 fn test_complex_f64_pow_nan_base_ok_exponent() {
1416 let base = Complex::new(f64::NAN, 0.0);
1417 let exponent = 3.0;
1418 let result = base.try_pow(&exponent);
1419 assert!(result.is_err());
1420
1421 let base = Complex::new(0.0, f64::NAN);
1422 let result = base.try_pow(&exponent);
1423 assert!(result.is_err());
1424 }
1425
1426 #[test]
1427 fn test_complex_f64_pow_infinity_base_ok_exponent() {
1428 let base = Complex::new(f64::INFINITY, 0.0);
1429 let exponent = 3.0;
1430 let result = base.try_pow(&exponent);
1431 assert!(result.is_err());
1432
1433 let base = Complex::new(0.0, f64::INFINITY);
1434 let result = base.try_pow(&exponent);
1435 assert!(result.is_err());
1436 }
1437
1438 #[test]
1439 fn test_complex_f64_pow_ok_base_negative_exponent() {
1440 let base = Complex::new(2.0, 3.0);
1441 let exponent = -2.0;
1442 let expected_result = Complex::new(-0.029585798816568046, -0.07100591715976332);
1443 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1444 }
1445
1446 #[test]
1447 fn test_complex_f64_pow_negative_base_positive_exponent() {
1448 let base = Complex::new(-2.0, -3.0);
1449 let exponent = 3.0;
1450 let expected_result = Complex::new(46.0, -8.99999999999999);
1451 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1452 }
1453
1454 #[test]
1455 fn test_complex_f64_pow_negative_base_negative_exponent() {
1456 let base = Complex::new(-2.0, -3.0);
1457 let exponent = -3.0;
1458 let expected_result = Complex::new(0.02093764223941739, 0.004096495220755572);
1459 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1460 }
1461 }
1462 }
1463
1464 #[cfg(feature = "rug")]
1465 mod rug53 {
1466 use super::*;
1467 use rug::{Complex, Float};
1468
1469 mod real_base {
1470 use super::*;
1471
1472 #[test]
1473 fn test_realrug_pow_valid() {
1474 let base =
1475 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1476 let exponent =
1477 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1478 let expected_result =
1479 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 8.0)).unwrap();
1480 assert_eq!(base.clone().pow(&exponent), expected_result);
1481 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1482 }
1483
1484 #[test]
1485 fn test_realrug_pow_zero_exponent() {
1486 let base =
1487 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1488 let exponent =
1489 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1490 let expected_result =
1491 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1492 assert_eq!(base.clone().pow(&exponent), expected_result);
1493 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1494 }
1495
1496 #[test]
1497 fn test_realrug_pow_one_exponent() {
1498 let base =
1499 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1500 let exponent =
1501 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1502 let expected_result =
1503 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1504 assert_eq!(base.clone().pow(&exponent), expected_result);
1505 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1506 }
1507
1508 #[test]
1509 fn test_realrug_pow_zero_base() {
1510 let base =
1511 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1512 let exponent =
1513 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1514 let expected_result =
1515 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1516 assert_eq!(base.clone().pow(&exponent), expected_result);
1517 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1518 }
1519
1520 #[test]
1521 fn test_realrug_pow_negative_exponent() {
1522 let base =
1523 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1524 let exponent =
1525 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1526 let expected_result =
1527 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.25)).unwrap();
1528 assert_eq!(base.clone().pow(&exponent), expected_result);
1529 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1530 }
1531
1532 #[test]
1533 fn test_realrug_pow_negative_base_positive_exponent() {
1534 let base =
1535 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1536 let exponent =
1537 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1538 let result = base.try_pow(&exponent);
1539 assert!(matches!(
1540 result,
1541 Err(PowRealBaseRealExponentErrors::Input { .. })
1542 ));
1543 }
1544
1545 #[test]
1546 fn test_realrug_pow_negative_base_negative_exponent() {
1547 let base =
1548 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1549 let exponent =
1550 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -3.0)).unwrap();
1551 let result = base.try_pow(&exponent);
1552 assert!(matches!(
1553 result,
1554 Err(PowRealBaseRealExponentErrors::Input { .. })
1555 ));
1556 }
1557 }
1558
1559 mod complex_base {
1560 use super::*;
1561
1562 #[test]
1563 fn test_complex_rug_float_pow_valid() {
1564 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1565 53,
1566 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1567 ))
1568 .unwrap();
1569 let exponent =
1570 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 2.0)).unwrap();
1571 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1572 53,
1573 (Float::with_val(53, -5.0), Float::with_val(53, 12.0)),
1574 ))
1575 .unwrap();
1576 assert_eq!(base.clone().pow(&exponent), expected_result);
1577 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1578 }
1579
1580 #[test]
1581 fn test_complex_rug_float_pow_zero_exponent() {
1582 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1583 53,
1584 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1585 ))
1586 .unwrap();
1587 let exponent =
1588 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 0.0)).unwrap();
1589 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1590 53,
1591 (Float::with_val(53, 1.0), Float::with_val(53, 0.0)),
1592 ))
1593 .unwrap();
1594 assert_eq!(base.clone().pow(&exponent), expected_result);
1595 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1596 }
1597
1598 #[test]
1599 fn test_complex_rug_float_pow_one_exponent() {
1600 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1601 53,
1602 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1603 ))
1604 .unwrap();
1605 let exponent =
1606 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 1.0)).unwrap();
1607 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1608 53,
1609 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1610 ))
1611 .unwrap();
1612 assert_eq!(base.clone().pow(&exponent), expected_result);
1613 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1614 }
1615
1616 #[test]
1617 fn test_complex_rug_float_pow_zero_base() {
1618 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1619 53,
1620 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1621 ))
1622 .unwrap();
1623 let exponent =
1624 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1625 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1626 53,
1627 (Float::with_val(53, 0.0), Float::with_val(53, 0.0)),
1628 ))
1629 .unwrap();
1630 assert_eq!(base.clone().pow(&exponent), expected_result);
1631 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1632 }
1633
1634 #[test]
1635 fn test_complex_rug_float_pow_negative_exponent() {
1636 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1637 53,
1638 (Float::with_val(53, 2.0), Float::with_val(53, 3.0)),
1639 ))
1640 .unwrap();
1641 let exponent =
1642 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -2.0)).unwrap();
1643 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1644 53,
1645 (
1646 Float::with_val(53, -0.029585798816568046),
1647 Float::with_val(53, -0.07100591715976332),
1648 ),
1649 ))
1650 .unwrap();
1651 assert_eq!(base.clone().pow(&exponent), expected_result);
1652 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1653 }
1654
1655 #[test]
1656 fn test_complex_rug_float_pow_negative_base_positive_exponent() {
1657 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1658 53,
1659 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1660 ))
1661 .unwrap();
1662 let exponent =
1663 RealRugStrictFinite::<53>::try_new(Float::with_val(53, 3.0)).unwrap();
1664 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1665 53,
1666 (Float::with_val(53, 46.0), Float::with_val(53, -9.0)),
1667 ))
1668 .unwrap();
1669 assert_eq!(base.clone().pow(&exponent), expected_result);
1670 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1671 }
1672
1673 #[test]
1674 fn test_complex_rug_float_pow_negative_base_negative_exponent() {
1675 let base = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1676 53,
1677 (Float::with_val(53, -2.0), Float::with_val(53, -3.0)),
1678 ))
1679 .unwrap();
1680 let exponent =
1681 RealRugStrictFinite::<53>::try_new(Float::with_val(53, -3.0)).unwrap();
1682 let expected_result = ComplexRugStrictFinite::<53>::try_new(Complex::with_val(
1683 53,
1684 (
1685 Float::with_val(53, 2.0937642239417388e-2),
1686 Float::with_val(53, 4.096495220755576e-3),
1687 ),
1688 ))
1689 .unwrap();
1690 assert_eq!(base.clone().pow(&exponent), expected_result);
1691 assert_eq!(base.try_pow(&exponent).unwrap(), expected_result);
1692 }
1693 }
1694 }
1695 }
1696}
1697