ft_lib 1.0.3

Manual implementation of some math functions.
Documentation
use crate::ft_abs::ft_abs;

pub fn ft_sqrt(number: f64) -> f64 {
    if number < 0.0 {
        return f64::NAN;
    }
    if number == 0.0 {
        return 0.0;
    }

    let mut guess: f64 = number;
    let mut prev_guess: f64 = 0.0;
    let precision: f64 = 1.0e-10;

    while ft_abs(guess - prev_guess) > precision {
        prev_guess = guess;
        guess = (guess + number / guess) / 2.0;
    }

    guess
}

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

    #[test]
    fn test_positive_numbers() {
        assert!((ft_sqrt(4.0) - 2.0).abs() < 1e-10);
        assert!((ft_sqrt(16.0) - 4.0).abs() < 1e-10);
        assert!((ft_sqrt(25.0) - 5.0).abs() < 1e-10);
    }

    #[test]
    fn test_zero() {
        assert!((ft_sqrt(0.0) - 0.0).abs() < 1e-10);
    }

    #[test]
    fn test_negative_number() {
        assert!(ft_sqrt(-1.0).is_nan());
        assert!(ft_sqrt(-100.0).is_nan());
    }

    #[test]
    fn test_large_numbers() {
        let large_number = 1e12;
        assert!((ft_sqrt(large_number) - large_number.sqrt()).abs() < 1e-5);
    }

    #[test]
    fn test_small_numbers() {
        let small_number = 1e-6;
        assert!((ft_sqrt(small_number) - small_number.sqrt()).abs() < 1e-6);
    }

    #[test]
    fn test_high_precision() {
        let precision_case = 2.0;
        assert!((ft_sqrt(precision_case) - precision_case.sqrt()).abs() < 1e-10);
    }

    #[test]
    fn test_large_float() {
        let large_float = 1e20;
        assert!((ft_sqrt(large_float) - large_float.sqrt()).abs() < 1e-5);
    }

    #[test]
    fn test_tiny_float() {
        let tiny_float: f64 = 1e-10;
        assert!((ft_sqrt(tiny_float) - tiny_float.sqrt()).abs() < 1e-5);
    }

    #[test]
    fn test_perfect_squares() {
        assert_eq!(ft_sqrt(0.0), 0.0);
        assert_eq!(ft_sqrt(1.0), 1.0);
        assert_eq!(ft_sqrt(4.0), 2.0);
        assert_eq!(ft_sqrt(9.0), 3.0);
        assert_eq!(ft_sqrt(16.0), 4.0);
    }

    #[test]
    fn test_non_perfect_squares() {
        assert!((ft_sqrt(2.0) - 1.4142135623730951).abs() < 1e-10);
        assert!((ft_sqrt(3.0) - 1.7320508075688772).abs() < 1e-10);
        assert!((ft_sqrt(5.0) - 2.23606797749979).abs() < 1e-10);
    }

    #[test]
    fn test_fractions() {
        assert!((ft_sqrt(0.25) - 0.5).abs() < 1e-10);
        assert!((ft_sqrt(0.5) - 0.7071067811865476).abs() < 1e-10);
        assert!((ft_sqrt(2.25) - 1.5).abs() < 1e-10);
    }

    #[test]
    fn test_negative() {
        assert!(ft_sqrt(-1.0).is_nan());
        assert!(ft_sqrt(-0.5).is_nan());
        assert!(ft_sqrt(-f64::MIN_POSITIVE).is_nan());
    }

    #[test]
    fn test_large_numbers2() {
        assert!((ft_sqrt(1e16) - 1e8).abs() < 1e-10);
        assert!((ft_sqrt(1e20) - 1e10).abs() < 1e-10);
    }
}