mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
math.big: remove Newton-raphson division, remove related tests (#25168)
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
This commit is contained in:
parent
603cd90337
commit
38519eca27
3 changed files with 1 additions and 121 deletions
|
@ -239,16 +239,10 @@ fn divide_array_by_digit(operand_a []u64, divisor u64, mut quotient []u64, mut r
|
||||||
shrink_tail_zeros(mut remainder)
|
shrink_tail_zeros(mut remainder)
|
||||||
}
|
}
|
||||||
|
|
||||||
const newton_division_limit = 1_000_000
|
|
||||||
|
|
||||||
@[inline]
|
@[inline]
|
||||||
fn divide_array_by_array(operand_a []u64, operand_b []u64, mut quotient []u64, mut remainder []u64) {
|
fn divide_array_by_array(operand_a []u64, operand_b []u64, mut quotient []u64, mut remainder []u64) {
|
||||||
if operand_a.len >= newton_division_limit {
|
|
||||||
newton_divide_array_by_array(operand_a, operand_b, mut quotient, mut remainder)
|
|
||||||
} else {
|
|
||||||
binary_divide_array_by_array(operand_a, operand_b, mut quotient, mut remainder)
|
binary_divide_array_by_array(operand_a, operand_b, mut quotient, mut remainder)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Shifts the contents of the original array by the given amount of bits to the left.
|
// Shifts the contents of the original array by the given amount of bits to the left.
|
||||||
// This function assumes that the amount is less than `digit_bits`. The storage is expected to
|
// This function assumes that the amount is less than `digit_bits`. The storage is expected to
|
||||||
|
|
|
@ -24,57 +24,6 @@ fn (i &Integer) shrink_tail_zeros() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppose operand_a bigger than operand_b and both not null.
|
|
||||||
// Both quotient and remaider are already allocated but of length 0
|
|
||||||
// TODO: the manualfree tag here is a workaround for compilation with -autofree. Remove it, when the -autofree bug is fixed.
|
|
||||||
@[manualfree]
|
|
||||||
fn newton_divide_array_by_array(operand_a []u64, operand_b []u64, mut quotient []u64, mut remainder []u64) {
|
|
||||||
// transform back to Integers (on the stack without allocation)
|
|
||||||
a := Integer{
|
|
||||||
signum: 1
|
|
||||||
digits: operand_a
|
|
||||||
}
|
|
||||||
b := Integer{
|
|
||||||
signum: 1
|
|
||||||
digits: operand_b
|
|
||||||
}
|
|
||||||
|
|
||||||
k := a.bit_len() + b.bit_len() // a*b < 2**k
|
|
||||||
mut x := integer_from_int(2) // 0 < x < 2**(k+1)/b // initial guess for convergence
|
|
||||||
// https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division
|
|
||||||
// use 48/17 - (32/17)*D (divisor)
|
|
||||||
// where D - Divisor B adjusted to fit 0.5-1 range by replacing the exponent field with 8'd126
|
|
||||||
// 0x0f0f0f0f0f0f0f0f * 0x11 == 0xffffffff_ffffffff = -1
|
|
||||||
// 0x0f0f0f0f0f0f0f0f = -1/17
|
|
||||||
initial_guess := (((integer_from_int(48) - (integer_from_int(32) * b)) * integer_from_i64(0x0f0f0f0f0f0f0f0f)).right_shift(64)).neg() // / 17 == 0x11
|
|
||||||
if initial_guess > zero_int {
|
|
||||||
x = initial_guess
|
|
||||||
}
|
|
||||||
mut lastx := integer_from_int(0)
|
|
||||||
pow2_k_plus_1 := pow2(k + 1) // outside of the loop to optimize allocatio
|
|
||||||
for lastx != x { // main loop
|
|
||||||
lastx = x
|
|
||||||
x = (x * (pow2_k_plus_1 - (x * b))).right_shift(u32(k))
|
|
||||||
}
|
|
||||||
if x * b < pow2(k) {
|
|
||||||
x.inc()
|
|
||||||
}
|
|
||||||
mut q := (a * x).right_shift(u32(k))
|
|
||||||
// possible adjustments. see literature
|
|
||||||
if q * b > a {
|
|
||||||
q.dec()
|
|
||||||
}
|
|
||||||
mut r := a - (q * b)
|
|
||||||
if r >= b {
|
|
||||||
q.inc()
|
|
||||||
r -= b
|
|
||||||
}
|
|
||||||
quotient = q.digits.clone()
|
|
||||||
remainder = r.digits.clone()
|
|
||||||
|
|
||||||
shrink_tail_zeros(mut remainder)
|
|
||||||
}
|
|
||||||
|
|
||||||
// debug_u64_str output a `[]u64`
|
// debug_u64_str output a `[]u64`
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn debug_u64_str(a []u64) string {
|
fn debug_u64_str(a []u64) string {
|
||||||
|
|
|
@ -128,66 +128,3 @@ fn test_multiply_karatsuba_05() {
|
||||||
}
|
}
|
||||||
assert c == expected.digits
|
assert c == expected.digits
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_newton_divide_03() {
|
|
||||||
a := [u64(0), 4]
|
|
||||||
b := [u64(0), 1]
|
|
||||||
mut q := []u64{cap: a.len - b.len + 1}
|
|
||||||
mut r := []u64{cap: a.len}
|
|
||||||
|
|
||||||
newton_divide_array_by_array(a, b, mut q, mut r)
|
|
||||||
assert q == [u64(4)]
|
|
||||||
assert r == []u64{len: 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_newton_divide_04() {
|
|
||||||
a := [u64(2), 4]
|
|
||||||
b := [u64(0), 1]
|
|
||||||
mut q := []u64{cap: a.len - b.len + 1}
|
|
||||||
mut r := []u64{cap: a.len}
|
|
||||||
|
|
||||||
newton_divide_array_by_array(a, b, mut q, mut r)
|
|
||||||
assert q == [u64(4)]
|
|
||||||
assert r == [u64(2)]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_newton_divide_05() {
|
|
||||||
a := [u64(2), 4, 5]
|
|
||||||
b := [u64(0), 1]
|
|
||||||
mut q := []u64{cap: a.len - b.len + 1}
|
|
||||||
mut r := []u64{cap: a.len}
|
|
||||||
|
|
||||||
newton_divide_array_by_array(a, b, mut q, mut r)
|
|
||||||
assert q == [u64(4), 5]
|
|
||||||
assert r == [u64(2)]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_newton_divide_06() {
|
|
||||||
a := [u64(2), 4, 5, 3]
|
|
||||||
b := [u64(0), 0x8000]
|
|
||||||
mut q := []u64{cap: a.len - b.len + 1}
|
|
||||||
mut r := []u64{cap: a.len}
|
|
||||||
|
|
||||||
newton_divide_array_by_array(a, b, mut q, mut r)
|
|
||||||
assert q == [u64(0xa000_0000_0000), 0x6000_0000_0000]
|
|
||||||
assert r == [u64(2), 4]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_newton_divide_07() {
|
|
||||||
a := integer_from_string('52348074924977237255285644820010078601114587486470740900886892189662650320988400136613780986308710610258879824881256666730655821800564143426560480113864123642197317383052431412305975584645367703594190956925565749714310612399025459615546540332117815550470167143256687163102859337019449165214274088466835988832405507818643018779158891710706073875995722420460085757') or {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
b := integer_from_string('977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688531898668229388286706296786321423078510899614439367') or {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
mut q := []u64{cap: a.digits.len - b.digits.len + 1}
|
|
||||||
mut r := []u64{cap: a.digits.len}
|
|
||||||
|
|
||||||
newton_divide_array_by_array(a.digits, b.digits, mut q, mut r)
|
|
||||||
quotient := Integer{
|
|
||||||
signum: 1
|
|
||||||
digits: q
|
|
||||||
}
|
|
||||||
assert quotient.str() == '53575430359313366047421252453000090528070240585276680372187519418517552556246806124659918940784792906379733645877657341259357264284615702179922887873492874019672838874121154927105373025311855709389770910765'
|
|
||||||
assert r == [u64(2)]
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue