use spirix::*;
#[test]
fn test_division_by_zero_handling() {
let normal = ScalarF5E3::from(42.0);
let zero = ScalarF5E3::ZERO;
let result = normal / zero;
assert!(result.is_infinite());
let zero_div_zero = zero / zero;
assert!(zero_div_zero.is_undefined());
let infinity = ScalarF5E3::INFINITY;
let inf_div_inf = infinity / infinity;
assert!(inf_div_inf.is_undefined());
let normal_div_inf = normal / infinity;
assert!(normal_div_inf.is_zero());
let inf_div_normal = infinity / normal;
assert!(inf_div_normal.is_infinite());
}
#[test]
fn test_square_root_error_handling() {
let negative = ScalarF5E3::from(-4.0);
let sqrt_neg = negative.sqrt();
assert!(sqrt_neg.is_undefined());
let sqrt_zero = ScalarF5E3::ZERO.sqrt();
assert!(sqrt_zero.is_zero());
let positive = ScalarF5E3::from(4.0);
let sqrt_pos = positive.sqrt();
assert!(sqrt_pos.is_normal());
let sqrt_inf = ScalarF5E3::INFINITY.sqrt();
assert!(sqrt_inf.is_infinite());
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let sqrt_undef = undefined.sqrt();
assert!(sqrt_undef.is_undefined());
}
#[test]
fn test_logarithm_error_handling() {
let ln_zero = ScalarF5E3::ZERO.ln();
assert!(ln_zero.is_infinite());
let negative = ScalarF5E3::from(-1.0);
let ln_neg = negative.ln();
assert!(ln_neg.is_undefined());
let positive = ScalarF5E3::from(2.718);
let ln_pos = positive.ln();
assert!(ln_pos.is_normal());
let ln_inf = ScalarF5E3::INFINITY.ln();
assert!(ln_inf.is_infinite());
let ln_one = ScalarF5E3::ONE.ln();
assert!(
ln_one.is_zero()
|| (ln_one.is_normal() && {
let val: f32 = ln_one.into();
val.abs() < 1e-6
})
);
}
#[test]
fn test_power_function_error_handling() {
let zero = ScalarF5E3::ZERO;
let one = ScalarF5E3::ONE;
let negative = ScalarF5E3::from(-2.0);
let zero_pow_zero = zero.pow(zero);
assert!(zero_pow_zero.is_normal());
let zero_pow_neg = zero.pow(negative);
assert!(zero_pow_neg.is_undefined());
let zero_pow_pos = zero.pow(one);
assert!(zero_pow_pos.is_undefined());
let neg_pow_frac = negative.pow(ScalarF5E3::from(0.5));
assert!(neg_pow_frac.is_undefined());
let neg_pow_int = negative.pow(ScalarF5E3::from(2.0));
assert!(neg_pow_int.is_undefined());
let inf_pow_zero = ScalarF5E3::INFINITY.pow(zero);
assert!(inf_pow_zero.is_normal());
}
#[test]
fn test_trigonometric_function_error_handling() {
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let infinity = ScalarF5E3::INFINITY;
assert!(undefined.sin().is_undefined());
assert!(undefined.cos().is_undefined());
assert!(undefined.tan().is_undefined());
assert!(infinity.sin().is_infinite());
assert!(infinity.cos().is_normal());
assert!(infinity.tan().is_infinite());
let invalid_asin = ScalarF5E3::from(2.0).asin(); assert!(invalid_asin.is_undefined());
let invalid_acos = ScalarF5E3::from(-2.0).acos(); assert!(invalid_acos.is_undefined());
let valid_asin = ScalarF5E3::from(0.5).asin();
assert!(valid_asin.is_normal());
let valid_acos = ScalarF5E3::from(0.5).acos();
assert!(valid_acos.is_normal());
}
#[test]
fn test_hyperbolic_function_error_handling() {
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let infinity = ScalarF5E3::INFINITY;
assert!(undefined.sinh().is_undefined());
assert!(undefined.cosh().is_undefined());
assert!(undefined.tanh().is_undefined());
assert!(infinity.sinh().is_infinite());
assert!(infinity.cosh().is_normal());
let tanh_inf = infinity.tanh();
assert!(tanh_inf.is_infinite());
}
#[test]
fn test_undefined_state_propagation_chain() {
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let normal = ScalarF5E3::from(42.0);
let chain_result = ((undefined + normal) * ScalarF5E3::from(2.0))
.pow(ScalarF5E3::from(3.0))
.sin()
.ln()
.exp()
.sqrt()
.magnitude();
assert!(chain_result.is_undefined());
let undefined2 = ScalarF5E3::from(-1.0).sqrt(); let mixed_undefined = undefined + undefined2;
assert!(mixed_undefined.is_undefined());
assert!((undefined + ScalarF5E3::INFINITY).is_undefined());
assert!((undefined * ScalarF5E3::ZERO).is_undefined());
assert!((undefined / ScalarF5E3::INFINITY).is_undefined());
}
#[test]
fn test_infinity_arithmetic_edge_cases() {
let infinity = ScalarF5E3::INFINITY;
let neg_infinity = -infinity;
let normal = ScalarF5E3::from(42.0);
let zero = ScalarF5E3::ZERO;
let inf_plus_inf = infinity + infinity;
assert!(inf_plus_inf.is_undefined());
let inf_minus_inf = infinity - infinity;
assert!(inf_minus_inf.is_undefined());
let inf_plus_neg_inf = infinity + neg_infinity;
assert!(inf_plus_neg_inf.is_undefined());
let inf_times_pos = infinity * normal;
assert!(inf_times_pos.is_infinite());
let inf_times_neg = infinity * (-normal);
assert!(inf_times_neg.is_infinite());
let inf_times_zero = infinity * zero;
assert!(inf_times_zero.is_undefined());
let zero_times_inf = zero * infinity;
assert!(zero_times_inf.is_undefined());
let inf_div_inf = infinity / infinity;
assert!(inf_div_inf.is_undefined());
let normal_div_inf = normal / infinity;
assert!(normal_div_inf.is_zero());
}
#[test]
fn test_escaped_value_error_conditions() {
let exploded = ScalarF5E3::MAX * ScalarF5E3::from(10.0);
let vanished = ScalarF5E3::MIN_POS / ScalarF5E3::from(10.0);
assert!(exploded.exploded());
assert!(vanished.vanished());
let exploded_squared = exploded * exploded;
assert!(exploded_squared.exploded());
let vanished_squared = vanished * vanished;
assert!(vanished_squared.vanished());
let exploded_div_exploded = exploded / exploded;
let vanished_div_vanished = vanished / vanished;
let exploded_plus_normal = exploded + ScalarF5E3::from(1.0);
assert!(exploded_plus_normal.is_undefined());
let vanished_plus_vanished = vanished + vanished;
assert!(vanished_plus_vanished.is_undefined());
}
#[test]
fn test_complex_error_propagation() {
let normal_circle = CircleF5E3::from((3.0, 4.0));
let undefined_scalar = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let undefined_circle = CircleF5E3::from((f32::NAN, 1.0));
let complex_add = normal_circle + undefined_circle;
assert!(complex_add.r().is_undefined());
assert!(complex_add.i().is_undefined());
let complex_mult = normal_circle * undefined_circle;
assert!(complex_mult.r().is_undefined());
assert!(complex_mult.i().is_undefined());
let zero_circle = CircleF5E3::from((0.0, 0.0));
let div_by_zero_circle = normal_circle / zero_circle;
assert!(div_by_zero_circle.r().is_infinite());
assert!(div_by_zero_circle.i().is_infinite());
let undefined_circle_exp = undefined_circle.exp();
assert!(undefined_circle_exp.r().is_undefined());
let undefined_circle_ln = undefined_circle.ln();
assert!(undefined_circle_ln.r().is_undefined());
}
#[test]
fn test_conversion_error_handling() {
let undefined = ScalarF5E3::ZERO / ScalarF5E3::ZERO;
let exploded = ScalarF5E3::MAX * ScalarF5E3::from(10.0);
let vanished = ScalarF5E3::MIN_POS / ScalarF5E3::from(10.0);
let undefined_as_f32: f32 = undefined.into();
assert!(undefined_as_f32.is_nan() || undefined_as_f32.is_infinite());
let exploded_as_f32: f32 = exploded.into();
assert!(exploded_as_f32.is_infinite() || exploded_as_f32.abs() > 1e30);
let vanished_as_f32: f32 = vanished.into();
assert!(vanished_as_f32 == 0.0 || vanished_as_f32.abs() < 1e-30);
let nan_input = f32::NAN;
let inf_input = f32::INFINITY;
let from_nan = ScalarF5E3::from(nan_input);
assert!(from_nan.is_undefined());
let from_inf = ScalarF5E3::from(inf_input);
assert!(from_inf.is_infinite());
}
#[test]
fn test_edge_case_combinations() {
let values = [
ScalarF5E3::ZERO,
ScalarF5E3::ONE,
ScalarF5E3::INFINITY,
ScalarF5E3::POS_NORMAL_EPSILON,
ScalarF5E3::MAX,
ScalarF5E3::MIN,
ScalarF5E3::MIN_POS,
ScalarF5E3::MAX_NEG,
ScalarF5E3::ZERO / ScalarF5E3::ZERO, ScalarF5E3::MAX * ScalarF5E3::from(2.0), ScalarF5E3::MIN_POS / ScalarF5E3::from(2.0), ];
for &a in &values {
for &b in &values {
let sum = a + b;
assert!(
sum.is_normal()
|| sum.is_zero()
|| sum.is_infinite()
|| sum.is_undefined()
|| sum.exploded()
|| sum.vanished()
);
let product = a * b;
assert!(
product.is_normal()
|| product.is_zero()
|| product.is_infinite()
|| product.is_undefined()
|| product.exploded()
|| product.vanished()
);
let quotient = a / b;
assert!(
quotient.is_normal()
|| quotient.is_zero()
|| quotient.is_infinite()
|| quotient.is_undefined()
|| quotient.exploded()
|| quotient.vanished()
);
let difference = a - b;
assert!(
difference.is_normal()
|| difference.is_zero()
|| difference.is_infinite()
|| difference.is_undefined()
|| difference.exploded()
|| difference.vanished()
);
}
}
}