use super::funejson::Value; use super::math_gcd_lcm_gcd::gcd; use super::math_gcd_lcm_lcm::lcm; /// Greatest common divisor and least common multiple of two integers. /// /// Both are returned together because a caller needing one nearly always /// needs the other (common denominators, repeating schedules). /// /// # Panics /// Panics if either input is outside ±(2^53 - 1), or the lcm is. pub fn gcd_lcm(a: i64, b: i64) -> GcdLcm { GcdLcm { gcd: gcd(a, b), lcm: lcm(a, b), } } pub fn gcd_lcm_to_value(result: &GcdLcm) -> Value { Value::obj(vec![ ("gcd", Value::Int(result.gcd)), ("lcm", Value::Int(result.lcm)), ]) } // Refuse what the typed signature cannot hold, with the wording TypeScript // and Python use, rather than let the conversion quietly truncate it. fn int_arg(v: &Value, name: &str) -> i64 { if let Value::Float(f) = v { if f.fract() != 0.0 { panic!("{} must be an integer, received {}", name, f); } } v.as_i64() } pub fn fune_vector(args: &[Value]) -> Value { gcd_lcm_to_value(&gcd_lcm(int_arg(&args[0], "a"), int_arg(&args[1], "b"))) }