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
|
// vfmt off
|
||||||
const div_mod_test_data = [
|
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, 10, 1, 3},
|
||||||
DivModTest{13, 9, 1, 4},
|
DivModTest{13, 9, 1, 4},
|
||||||
DivModTest{7, 5, 1, 2},
|
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.
|
// DO NOT use this method if the divisor has any chance of being 0.
|
||||||
fn (dividend Integer) div_mod_internal(divisor Integer) (Integer, Integer) {
|
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 q := []u32{cap: int_max(1, dividend.digits.len - divisor.digits.len + 1)}
|
||||||
mut r := []u32{cap: dividend.digits.len}
|
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)
|
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{
|
quotient := Integer{
|
||||||
signum: if q.len == 0 { 0 } else { 1 }
|
signum: if q.len == 0 { 0 } else { q_signum }
|
||||||
digits: q
|
digits: q
|
||||||
}
|
}
|
||||||
remainder := Integer{
|
remainder := Integer{
|
||||||
signum: if r.len == 0 { 0 } else { 1 }
|
signum: if r.len == 0 { 0 } else { r_signum }
|
||||||
digits: r
|
digits: r
|
||||||
}
|
}
|
||||||
return quotient, remainder
|
return quotient, remainder
|
||||||
|
Loading…
x
Reference in New Issue
Block a user