use oxinum_complex::{CBig, DBig, OxiNumError};
fn c(re: f64, im: f64) -> CBig {
CBig::from_f64(re, im).expect("finite parts")
}
fn assert_parts(z: &CBig, re: &str, im: &str) {
assert_eq!(z.re().to_string(), re, "real part");
assert_eq!(z.im().to_string(), im, "imag part");
}
#[test]
fn add_hand_computed() {
assert_parts(&(c(1.0, 2.0) + c(3.0, 4.0)), "4", "6");
}
#[test]
fn sub_hand_computed() {
assert_parts(&(c(1.0, 2.0) - c(3.0, 4.0)), "-2", "-2");
}
#[test]
fn mul_hand_computed() {
assert_parts(&(c(1.0, 2.0) * c(3.0, 4.0)), "-5", "10");
}
#[test]
fn div_hand_computed() {
assert_parts(&(c(3.0, 4.0) / c(1.0, 2.0)), "2.2", "-0.4");
}
#[test]
fn add_assign_and_sub_assign() {
let mut a = c(1.0, 2.0);
a += c(3.0, 4.0);
assert_parts(&a, "4", "6");
a -= &c(1.0, 1.0);
assert_parts(&a, "3", "5");
}
#[test]
fn mul_assign_and_div_assign() {
let mut a = c(1.0, 1.0);
a *= &c(1.0, 1.0);
assert_parts(&a, "0", "2");
a /= c(1.0, 1.0);
assert_parts(&a, "1", "1");
}
#[test]
fn checked_div_by_zero_is_div_by_zero_err() {
let z = c(1.0, 1.0);
assert!(matches!(
z.checked_div(&CBig::zero()),
Err(OxiNumError::DivByZero)
));
}
#[test]
fn checked_div_nonzero_is_ok() {
let q = c(3.0, 4.0)
.checked_div(&c(1.0, 2.0))
.expect("non-zero divisor");
assert_parts(&q, "2.2", "-0.4");
}
#[test]
#[should_panic]
fn div_operator_by_zero_panics() {
let z = c(1.0, 1.0);
let _ = z / CBig::zero();
}
#[test]
fn norm_sqr_is_exact_integer() {
assert_eq!(c(3.0, 4.0).norm_sqr(), DBig::from(25u32));
assert_eq!(c(3.0, 4.0).norm_sqr().to_string(), "25");
}
#[test]
fn conj_negates_imag() {
let z = c(2.0, -3.0);
assert_parts(&z.conj(), "2", "3");
assert_parts(&c(5.0, 0.0).conj(), "5", "0");
}
#[test]
fn neg_owned_and_borrowed() {
let z = c(2.0, -3.0);
assert_parts(&(-&z), "-2", "3");
assert_parts(&(-z), "-2", "3");
}
#[test]
fn from_dbig_pair_and_real() {
let z: CBig = (DBig::from(7), DBig::from(-4)).into();
assert_parts(&z, "7", "-4");
let r: CBig = DBig::from(5).into();
assert_parts(&r, "5", "0");
assert!(r.is_real());
}
#[test]
fn from_integer_pair_and_scalar() {
let z: CBig = (1i64, 2i64).into();
assert_parts(&z, "1", "2");
let r: CBig = 42i64.into();
assert_parts(&r, "42", "0");
assert!(r.is_real());
}
#[test]
fn default_equals_zero() {
let d = CBig::default();
assert!(d.is_zero());
assert!(d == CBig::zero());
}
#[test]
fn partial_eq_component_wise() {
assert!(c(1.5, -2.0) == c(1.5, -2.0));
assert!(c(1.5, -2.0) != c(1.5, 2.0));
assert!(c(1.5, -2.0) != c(-1.5, -2.0));
}
#[test]
fn display_positive_imag() {
assert_eq!(c(2.0, 3.0).to_string(), "2 + 3i");
}
#[test]
fn display_negative_imag() {
assert_eq!(c(2.0, -3.0).to_string(), "2 - 3i");
}
#[test]
fn display_fractional_negative_imag() {
assert_eq!(c(1.5, -2.25).to_string(), "1.5 - 2.25i");
}
#[test]
fn display_real_shows_zero_imag() {
let z: CBig = DBig::from(5).into();
assert_eq!(z.to_string(), "5 + 0i");
}