]> Repositorios git - scryer-prolog.git/commitdiff
fix signed modulus bug (#2134)
authorMark <[email protected]>
Sun, 29 Oct 2023 00:13:42 +0000 (18:13 -0600)
committerMark <[email protected]>
Sun, 29 Oct 2023 00:13:42 +0000 (18:13 -0600)
src/machine/arithmetic_ops.rs

index 92e9c5996c567215e57d9f8ec845e664ceabae0d..20c503a90c46d1d9d15a0b77d8bfcc194b1e490b 100644 (file)
@@ -1,4 +1,4 @@
-use dashu::base::{Abs, Gcd, UnsignedAbs};
+use dashu::base::{Abs, Gcd, Signed, UnsignedAbs};
 use dashu::integer::IBig;
 use dashu::integer::fast_div::ConstDivisor;
 use divrem::*;
@@ -852,7 +852,18 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
     fn ibig_rem_floor(n1: &Integer, n2: &Integer) -> Integer {
         let ring = ConstDivisor::new(n2.unsigned_abs());
         let n1 = n1.clone();
-        IBig::from(ring.reduce(n1).residue())
+
+        if n2.is_negative() {
+            let unsigned_result = IBig::from(ring.reduce(n1).residue());
+
+            if unsigned_result.is_zero() {
+                unsigned_result
+            } else {
+                unsigned_result + n2
+            }
+        } else {
+            IBig::from(ring.reduce(n1).residue())
+        }
     }
 
     match (x, y) {