1use crate::gcd;
2
3#[must_use]
16pub const fn checked_lcm(left: u64, right: u64) -> Option<u64> {
17 if left == 0 || right == 0 {
18 return Some(0);
19 }
20
21 let divisor = gcd(left, right);
22 (left / divisor).checked_mul(right)
23}
24
25#[must_use]
42pub fn lcm(left: u64, right: u64) -> u64 {
43 checked_lcm(left, right).unwrap_or_else(|| panic!("lcm overflowed u64"))
44}
45
46#[cfg(test)]
47mod tests {
48 use super::{checked_lcm, lcm};
49
50 #[test]
51 fn handles_zero_and_positive_cases() {
52 assert_eq!(checked_lcm(0, 0), Some(0));
53 assert_eq!(checked_lcm(0, 15), Some(0));
54 assert_eq!(checked_lcm(6, 15), Some(30));
55 assert_eq!(lcm(21, 6), 42);
56 }
57
58 #[test]
59 fn reports_overflow_through_checked_variant() {
60 assert_eq!(checked_lcm(u64::MAX, u64::MAX - 1), None);
61 }
62
63 #[test]
64 #[should_panic(expected = "lcm overflowed u64")]
65 fn plain_lcm_panics_on_overflow() {
66 let _ = lcm(u64::MAX, u64::MAX - 1);
67 }
68}