mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
math.big: add Newton and Karatsuba algorithms (#11487)
This commit is contained in:
@@ -109,10 +109,24 @@ fn subtract_digit_array(operand_a []u32, operand_b []u32, mut storage []u32) {
|
||||
}
|
||||
}
|
||||
|
||||
const karatsuba_multiplication_limit = 1_000_000
|
||||
|
||||
// set limit to choose algorithm
|
||||
|
||||
[inline]
|
||||
fn multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u32) {
|
||||
if operand_a.len >= big.karatsuba_multiplication_limit
|
||||
|| operand_b.len >= big.karatsuba_multiplication_limit {
|
||||
karatsuba_multiply_digit_array(operand_a, operand_b, mut storage)
|
||||
} else {
|
||||
simple_multiply_digit_array(operand_a, operand_b, mut storage)
|
||||
}
|
||||
}
|
||||
|
||||
// Multiplies the unsigned (non-negative) integers represented in a and b and the product is
|
||||
// stored in storage. It assumes that storage has length equal to the sum of lengths
|
||||
// of a and b. Length refers to length of array, that is, digit count.
|
||||
fn multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u32) {
|
||||
fn simple_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u32) {
|
||||
for b_index in 0 .. operand_b.len {
|
||||
mut carry := u64(0)
|
||||
for a_index in 0 .. operand_a.len {
|
||||
@@ -240,6 +254,17 @@ fn divide_array_by_digit(operand_a []u32, divisor u32, mut quotient []u32, mut r
|
||||
}
|
||||
}
|
||||
|
||||
const newton_division_limit = 10_000
|
||||
|
||||
[inline]
|
||||
fn divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient []u32, mut remainder []u32) {
|
||||
if operand_a.len >= big.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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 32. The storage is expected to
|
||||
// allocated with zeroes.
|
||||
|
||||
Reference in New Issue
Block a user