diff --git a/vlib/math/big/big_test.v b/vlib/math/big/big_test.v index e06d9c0512..daf59c5e61 100644 --- a/vlib/math/big/big_test.v +++ b/vlib/math/big/big_test.v @@ -248,6 +248,20 @@ struct DivModTest { // vfmt off const div_mod_test_data = [ + DivModTest{0, 7, 0, 0}, + DivModTest{0, -7, 0, 0}, + DivModTest{3, 7, 0, 3}, + DivModTest{-3, -7, 0, -3}, + DivModTest{-3, 7, 0, -3}, + DivModTest{3, -7, 0, 3}, + DivModTest{7, 3, 2, 1}, + DivModTest{-7, -3, 2, -1}, + DivModTest{-7, 3, -2, -1}, + DivModTest{7, -3, -2, 1}, + DivModTest{8, 2, 4, 0}, + DivModTest{-8, -2, 4, 0}, + DivModTest{-8, 2, -4, 0}, + DivModTest{8, -2, -4, 0}, DivModTest{13, 10, 1, 3}, DivModTest{13, 9, 1, 4}, DivModTest{7, 5, 1, 2}, diff --git a/vlib/math/big/integer.v b/vlib/math/big/integer.v index 733a318fd0..8d4a7fbc89 100644 --- a/vlib/math/big/integer.v +++ b/vlib/math/big/integer.v @@ -415,38 +415,31 @@ pub fn (multiplicand Integer) * (multiplier Integer) Integer { // // DO NOT use this method if the divisor has any chance of being 0. fn (dividend Integer) div_mod_internal(divisor Integer) (Integer, Integer) { - $if debug { - assert divisor.signum != 0 - } - - if dividend.signum == 0 { - return zero_int, zero_int - } - if divisor == one_int { - return dividend.clone(), zero_int - } - if divisor.signum == -1 { - q, r := dividend.div_mod_internal(divisor.neg()) - return q.neg(), r - } - if dividend.signum == -1 { - q, r := dividend.neg().div_mod_internal(divisor) - if r.signum == 0 { - return q.neg(), zero_int - } else { - return q.neg() - one_int, divisor - r - } - } - // Division for positive integers mut q := []u32{cap: int_max(1, dividend.digits.len - divisor.digits.len + 1)} mut r := []u32{cap: dividend.digits.len} + mut q_signum := 0 + mut r_signum := 0 + divide_digit_array(dividend.digits, divisor.digits, mut q, mut r) + if dividend.signum > 0 && divisor.signum > 0 { + q_signum = 1 + r_signum = 1 + } else if dividend.signum > 0 && divisor.signum < 0 { + q_signum = -1 + r_signum = 1 + } else if dividend.signum < 0 && divisor.signum > 0 { + q_signum = -1 + r_signum = -1 + } else { + q_signum = 1 + r_signum = -1 + } quotient := Integer{ - signum: if q.len == 0 { 0 } else { 1 } + signum: if q.len == 0 { 0 } else { q_signum } digits: q } remainder := Integer{ - signum: if r.len == 0 { 0 } else { 1 } + signum: if r.len == 0 { 0 } else { r_signum } digits: r } return quotient, remainder