This is an automated email from the ASF dual-hosted git repository.

jonah pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 8aad936e3b Compute gcd with u64 instead of i64 because of overflows 
(#11036)
8aad936e3b is described below

commit 8aad936e3b80833ccb70f2afabeb104b34182190
Author: Lorrens Pantelis <[email protected]>
AuthorDate: Fri Jun 21 18:46:22 2024 +0200

    Compute gcd with u64 instead of i64 because of overflows (#11036)
    
    * compute gcd with unsigned ints
    
    * add test for the i64::MAX cases
    
    * move unsigned_abs below zero test to remove unnecessary casts
    
    * add slt test for gcd on max values instead of unit tests
---
 datafusion/functions/src/math/gcd.rs          | 17 +++++++++--------
 datafusion/sqllogictest/test_files/scalar.slt | 10 ++++++++++
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/datafusion/functions/src/math/gcd.rs 
b/datafusion/functions/src/math/gcd.rs
index 41c9e4e233..d0199f7a22 100644
--- a/datafusion/functions/src/math/gcd.rs
+++ b/datafusion/functions/src/math/gcd.rs
@@ -88,16 +88,16 @@ fn gcd(args: &[ArrayRef]) -> Result<ArrayRef> {
 
 /// Computes greatest common divisor using Binary GCD algorithm.
 pub fn compute_gcd(x: i64, y: i64) -> i64 {
-    let mut a = x.wrapping_abs();
-    let mut b = y.wrapping_abs();
-
-    if a == 0 {
-        return b;
+    if x == 0 {
+        return y;
     }
-    if b == 0 {
-        return a;
+    if y == 0 {
+        return x;
     }
 
+    let mut a = x.unsigned_abs();
+    let mut b = y.unsigned_abs();
+
     let shift = (a | b).trailing_zeros();
     a >>= shift;
     b >>= shift;
@@ -112,7 +112,8 @@ pub fn compute_gcd(x: i64, y: i64) -> i64 {
         b -= a;
 
         if b == 0 {
-            return a << shift;
+            // because the input values are i64, casting this back to i64 is 
safe
+            return (a << shift) as i64;
         }
     }
 }
diff --git a/datafusion/sqllogictest/test_files/scalar.slt 
b/datafusion/sqllogictest/test_files/scalar.slt
index 04b0fa8aca..551c50e0a1 100644
--- a/datafusion/sqllogictest/test_files/scalar.slt
+++ b/datafusion/sqllogictest/test_files/scalar.slt
@@ -474,6 +474,16 @@ select gcd(null, null);
 ----
 NULL
 
+# scalar maxes and/or negative 1
+query III rowsort
+select 
+  gcd(9223372036854775807, -9223372036854775808), -- i64::MIN, i64::MAX
+  -- wait till fix, cause it fails gcd(-9223372036854775808, 
-9223372036854775808), -- -i64::MIN, i64::MIN
+  gcd(9223372036854775807, -1), -- i64::MAX, -1
+  gcd(-9223372036854775808, -1); -- i64::MIN, -1
+----
+1 1 1
+
 # gcd with columns
 query III rowsort
 select gcd(a, b), gcd(c, d), gcd(e, f) from signed_integers;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to