Skip to content

Commit 38519ec

Browse files
authored
math.big: remove Newton-raphson division, remove related tests (#25168)
1 parent 603cd90 commit 38519ec

3 files changed

Lines changed: 1 addition & 121 deletions

File tree

‎vlib/math/big/array_ops.v‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,15 +239,9 @@ fn divide_array_by_digit(operand_a []u64, divisor u64, mut quotient []u64, mut r
239239
shrink_tail_zeros(mut remainder)
240240
}
241241

242-
const newton_division_limit = 1_000_000
243-
244242
@[inline]
245243
fn divide_array_by_array(operand_a []u64, operand_b []u64, mut quotient []u64, mut remainder []u64) {
246-
if operand_a.len >= newton_division_limit {
247-
newton_divide_array_by_array(operand_a, operand_b, mut quotient, mut remainder)
248-
} else {
249-
binary_divide_array_by_array(operand_a, operand_b, mut quotient, mut remainder)
250-
}
244+
binary_divide_array_by_array(operand_a, operand_b, mut quotient, mut remainder)
251245
}
252246

253247
// Shifts the contents of the original array by the given amount of bits to the left.

‎vlib/math/big/special_array_ops.v‎

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,57 +24,6 @@ fn (i &Integer) shrink_tail_zeros() {
2424
}
2525
}
2626

27-
// suppose operand_a bigger than operand_b and both not null.
28-
// Both quotient and remaider are already allocated but of length 0
29-
// TODO: the manualfree tag here is a workaround for compilation with -autofree. Remove it, when the -autofree bug is fixed.
30-
@[manualfree]
31-
fn newton_divide_array_by_array(operand_a []u64, operand_b []u64, mut quotient []u64, mut remainder []u64) {
32-
// transform back to Integers (on the stack without allocation)
33-
a := Integer{
34-
signum: 1
35-
digits: operand_a
36-
}
37-
b := Integer{
38-
signum: 1
39-
digits: operand_b
40-
}
41-
42-
k := a.bit_len() + b.bit_len() // a*b < 2**k
43-
mut x := integer_from_int(2) // 0 < x < 2**(k+1)/b // initial guess for convergence
44-
// https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division
45-
// use 48/17 - (32/17)*D (divisor)
46-
// where D - Divisor B adjusted to fit 0.5-1 range by replacing the exponent field with 8'd126
47-
// 0x0f0f0f0f0f0f0f0f * 0x11 == 0xffffffff_ffffffff = -1
48-
// 0x0f0f0f0f0f0f0f0f = -1/17
49-
initial_guess := (((integer_from_int(48) - (integer_from_int(32) * b)) * integer_from_i64(0x0f0f0f0f0f0f0f0f)).right_shift(64)).neg() // / 17 == 0x11
50-
if initial_guess > zero_int {
51-
x = initial_guess
52-
}
53-
mut lastx := integer_from_int(0)
54-
pow2_k_plus_1 := pow2(k + 1) // outside of the loop to optimize allocatio
55-
for lastx != x { // main loop
56-
lastx = x
57-
x = (x * (pow2_k_plus_1 - (x * b))).right_shift(u32(k))
58-
}
59-
if x * b < pow2(k) {
60-
x.inc()
61-
}
62-
mut q := (a * x).right_shift(u32(k))
63-
// possible adjustments. see literature
64-
if q * b > a {
65-
q.dec()
66-
}
67-
mut r := a - (q * b)
68-
if r >= b {
69-
q.inc()
70-
r -= b
71-
}
72-
quotient = q.digits.clone()
73-
remainder = r.digits.clone()
74-
75-
shrink_tail_zeros(mut remainder)
76-
}
77-
7827
// debug_u64_str output a `[]u64`
7928
@[direct_array_access]
8029
fn debug_u64_str(a []u64) string {

‎vlib/math/big/special_array_ops_test.v‎

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -128,66 +128,3 @@ fn test_multiply_karatsuba_05() {
128128
}
129129
assert c == expected.digits
130130
}
131-
132-
fn test_newton_divide_03() {
133-
a := [u64(0), 4]
134-
b := [u64(0), 1]
135-
mut q := []u64{cap: a.len - b.len + 1}
136-
mut r := []u64{cap: a.len}
137-
138-
newton_divide_array_by_array(a, b, mut q, mut r)
139-
assert q == [u64(4)]
140-
assert r == []u64{len: 0}
141-
}
142-
143-
fn test_newton_divide_04() {
144-
a := [u64(2), 4]
145-
b := [u64(0), 1]
146-
mut q := []u64{cap: a.len - b.len + 1}
147-
mut r := []u64{cap: a.len}
148-
149-
newton_divide_array_by_array(a, b, mut q, mut r)
150-
assert q == [u64(4)]
151-
assert r == [u64(2)]
152-
}
153-
154-
fn test_newton_divide_05() {
155-
a := [u64(2), 4, 5]
156-
b := [u64(0), 1]
157-
mut q := []u64{cap: a.len - b.len + 1}
158-
mut r := []u64{cap: a.len}
159-
160-
newton_divide_array_by_array(a, b, mut q, mut r)
161-
assert q == [u64(4), 5]
162-
assert r == [u64(2)]
163-
}
164-
165-
fn test_newton_divide_06() {
166-
a := [u64(2), 4, 5, 3]
167-
b := [u64(0), 0x8000]
168-
mut q := []u64{cap: a.len - b.len + 1}
169-
mut r := []u64{cap: a.len}
170-
171-
newton_divide_array_by_array(a, b, mut q, mut r)
172-
assert q == [u64(0xa000_0000_0000), 0x6000_0000_0000]
173-
assert r == [u64(2), 4]
174-
}
175-
176-
fn test_newton_divide_07() {
177-
a := integer_from_string('52348074924977237255285644820010078601114587486470740900886892189662650320988400136613780986308710610258879824881256666730655821800564143426560480113864123642197317383052431412305975584645367703594190956925565749714310612399025459615546540332117815550470167143256687163102859337019449165214274088466835988832405507818643018779158891710706073875995722420460085757') or {
178-
panic(err)
179-
}
180-
b := integer_from_string('977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688531898668229388286706296786321423078510899614439367') or {
181-
panic(err)
182-
}
183-
mut q := []u64{cap: a.digits.len - b.digits.len + 1}
184-
mut r := []u64{cap: a.digits.len}
185-
186-
newton_divide_array_by_array(a.digits, b.digits, mut q, mut r)
187-
quotient := Integer{
188-
signum: 1
189-
digits: q
190-
}
191-
assert quotient.str() == '53575430359313366047421252453000090528070240585276680372187519418517552556246806124659918940784792906379733645877657341259357264284615702179922887873492874019672838874121154927105373025311855709389770910765'
192-
assert r == [u64(2)]
193-
}

0 commit comments

Comments
 (0)