pub(crate) mod arith;
pub(crate) mod big;
mod cmp;
mod ord;
#[cfg(feature = "serde")]
mod serde;
mod small;
mod traits;
pub use crate::complex::big::ParseComplexError;
pub use crate::complex::ord::OrdComplex;
pub use crate::complex::small::SmallComplex;
pub trait Prec {
fn prec(self) -> (u32, u32);
}
impl Prec for u32 {
#[inline]
fn prec(self) -> (u32, u32) {
(self, self)
}
}
impl Prec for (u32, u32) {
#[inline]
fn prec(self) -> (u32, u32) {
self
}
}
#[cfg(test)]
mod tests {
use crate::float::tests::Cmp;
use crate::float::Special;
use crate::{Assign, Complex};
use std::f64;
#[test]
fn check_from_str() {
let mut c = Complex::new(53);
c.assign(Complex::parse("(+0 -0)").unwrap());
assert_eq!(c, (0, 0));
assert!(c.real().is_sign_positive());
assert!(c.imag().is_sign_negative());
c.assign(Complex::parse("(5 6)").unwrap());
assert_eq!(c, (5, 6));
c.assign(Complex::parse_radix("(50 60)", 8).unwrap());
assert_eq!(c, (0o50, 0o60));
c.assign(Complex::parse_radix("33", 16).unwrap());
assert_eq!(c, (0x33, 0));
let bad_strings = [
("", None),
("(0 0) 0", None),
("(0 0 0)", None),
("(0) ", None),
("(, 0)", None),
("(0 )", None),
("(0, )", None),
("(0,,0 )", None),
(" ( 2)", None),
("+(1 1)", None),
("-(1. 1.)", None),
("(f 1)", None),
("(1 1@1a)", Some(16)),
("(8 )", Some(9)),
];
for &(s, radix) in bad_strings.iter() {
assert!(
Complex::parse_radix(s, radix.unwrap_or(10)).is_err(),
"{} parsed correctly",
s
);
}
let good_strings = [
("(inf -@inf@)", 10, Cmp::inf(false), Cmp::inf(true)),
("(+0e99 1.)", 2, Cmp::F64(0.0), Cmp::F64(1.0)),
("(+ 0 e 99, .1)", 2, Cmp::F64(0.0), Cmp::F64(0.5)),
("-9.9e1", 10, Cmp::F64(-99.0), Cmp::F64(0.0)),
(
" ( -@nan@( _ ) nan( 0 n ) ) ",
10,
Cmp::Nan(true),
Cmp::Nan(false),
),
];
for &(s, radix, r, i) in good_strings.iter() {
match Complex::parse_radix(s, radix) {
Ok(ok) => {
let c = Complex::with_val(53, ok);
assert_eq!(*c.real(), r, "real mismatch for {}", s);
assert_eq!(*c.imag(), i, "imaginary mismatch for {}", s);
}
Err(e) => panic!("could not parse {} because {:?}", s, e),
}
}
}
#[test]
fn check_formatting() {
let mut c = Complex::new((53, 53));
c.assign((Special::Zero, Special::NegZero));
assert_eq!(format!("{}", c), "(0.0 -0.0)");
assert_eq!(format!("{:?}", c), "(0.0 -0.0)");
assert_eq!(format!("{:+}", c), "(+0.0 -0.0)");
assert_eq!(format!("{:+}", *c.as_neg()), "(-0.0 +0.0)");
c.assign((2.7, f64::NEG_INFINITY));
assert_eq!(format!("{:.2}", c), "(2.7 -inf)");
assert_eq!(format!("{:+.8}", c), "(+2.7000000 -inf)");
assert_eq!(format!("{:.4e}", c), "(2.700 -inf)");
assert_eq!(format!("{:.4E}", c), "(2.700 -inf)");
assert_eq!(format!("{:16.2}", c), " (2.7 -inf)");
c.assign((-3.5, 11));
assert_eq!(format!("{:.4b}", c), "(-1.110e1 1.011e3)");
assert_eq!(format!("{:#.4b}", c), "(-0b1.110e1 0b1.011e3)");
assert_eq!(format!("{:.4o}", c), "(-3.400 1.300e1)");
assert_eq!(format!("{:#.4o}", c), "(-0o3.400 0o1.300e1)");
c.assign((3.5, -11));
assert_eq!(format!("{:.2x}", c), "(3.8 -b.0)");
assert_eq!(format!("{:#.2x}", c), "(0x3.8 -0xb.0)");
assert_eq!(format!("{:.2X}", c), "(3.8 -B.0)");
assert_eq!(format!("{:#.2X}", c), "(0x3.8 -0xB.0)");
}
}