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