//! F8 — Float64 monomers: MC_64–MC_71
//!
//! 64-bit floating-point arithmetic operations.

/// MC_64 — FADD: f64 addition.
pub fn fadd(a: f64, b: f64) -> f64 { a + b }

/// MC_65 — FSUB: f64 subtraction.
pub fn fsub(a: f64, b: f64) -> f64 { a - b }

/// MC_66 — FMUL: f64 multiplication.
pub fn fmul(a: f64, b: f64) -> f64 { a * b }

/// MC_67 — FDIV: f64 division. Returns 0.0 on division by zero.
pub fn fdiv(a: f64, b: f64) -> f64 {
    if b == 0.0 { 0.0 } else { a / b }
}

/// MC_68 — FABS: f64 absolute value.
pub fn fabs(a: f64) -> f64 { a.abs() }

/// MC_69 — FNEG: f64 negation.
pub fn fneg(a: f64) -> f64 { -a }

/// MC_70 — FSQRT: f64 square root. Returns 0.0 for negative inputs.
pub fn fsqrt(a: f64) -> f64 {
    if a < 0.0 { 0.0 } else { a.sqrt() }
}

/// MC_71 — FMOD: f64 modulo. Returns 0.0 on division by zero.
pub fn fmod_op(a: f64, b: f64) -> f64 {
    if b == 0.0 { 0.0 } else { a % b }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn float64_basic() {
        assert_eq!(fadd(1.0, 2.0), 3.0);
        assert_eq!(fsub(5.0, 3.0), 2.0);
        assert_eq!(fmul(3.0, 4.0), 12.0);
        assert_eq!(fdiv(10.0, 2.0), 5.0);
        assert_eq!(fdiv(1.0, 0.0), 0.0);
        assert_eq!(fabs(-42.0), 42.0);
        assert_eq!(fneg(5.0), -5.0);
        assert_eq!(fsqrt(9.0), 3.0);
        assert_eq!(fsqrt(-1.0), 0.0);
        assert_eq!(fmod_op(17.0, 5.0), 2.0);
        assert_eq!(fmod_op(1.0, 0.0), 0.0);
    }
}
