mirror of
https://github.com/vlang/v.git
synced 2025-08-04 02:07:28 -04:00
math.big: change the handling of negatives in div_mod() to match gmp and Julia, add tests (#24713)
This commit is contained in:
parent
12c20e3c1f
commit
6e271b2ae6
@ -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},
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user