From f3a92c655149a819bc1e0b0260945054c99d2936 Mon Sep 17 00:00:00 2001 From: Emilie Burgun Date: Sat, 18 Jan 2025 13:11:52 +0100 Subject: [PATCH] Fix min/2 and max/2 returning the cast version of its arguments It now behaves the same way as SWI-Prolog. --- src/machine/arithmetic_ops.rs | 38 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 3cd1d9d8..53289012 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -455,13 +455,8 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result { Ok(Number::Fixnum(n2)) } } - (Number::Integer(n1), Number::Integer(n2)) => { - if n1 > n2 { - Ok(Number::Integer(n1)) - } else { - Ok(Number::Integer(n2)) - } - } + (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(cmp::max(n1, n2))), + (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(cmp::max(r1, r2))), (n1, n2) => { let stub_gen = || { let max_atom = atom!("max"); @@ -471,7 +466,15 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result { let f1 = try_numeric_result!(result_f(&n1), stub_gen)?; let f2 = try_numeric_result!(result_f(&n2), stub_gen)?; - Ok(Number::Float(cmp::max(OrderedFloat(f1), OrderedFloat(f2)))) + match OrderedFloat(f1).cmp(&OrderedFloat(f2)) { + cmp::Ordering::Less => Ok(n2), + cmp::Ordering::Equal => { + // Note: n1 and n2 were compared as floats, + // so we return the second argument as a floating point value. + Ok(Number::Float(OrderedFloat(f2))) + } + cmp::Ordering::Greater => Ok(n1), + } } } } @@ -499,13 +502,8 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result { Ok(Number::Fixnum(n2)) } } - (Number::Integer(n1), Number::Integer(n2)) => { - if n1 < n2 { - Ok(Number::Integer(n1)) - } else { - Ok(Number::Integer(n2)) - } - } + (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(cmp::min(n1, n2))), + (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(cmp::min(r1, r2))), (n1, n2) => { let stub_gen = || { let min_atom = atom!("min"); @@ -515,7 +513,15 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result { let f1 = try_numeric_result!(result_f(&n1), stub_gen)?; let f2 = try_numeric_result!(result_f(&n2), stub_gen)?; - Ok(Number::Float(cmp::min(OrderedFloat(f1), OrderedFloat(f2)))) + match OrderedFloat(f1).cmp(&OrderedFloat(f2)) { + cmp::Ordering::Less => Ok(n1), + cmp::Ordering::Equal => { + // Note: n1 and n2 were compared as floats, + // so we return the first argument as a floating point value. + Ok(Number::Float(OrderedFloat(f1))) + } + cmp::Ordering::Greater => Ok(n2), + } } } } -- 2.54.0