math.big: fix toom-cook 3-way multiplication (#24888)

This commit is contained in:
Mike 2025-07-13 18:36:46 +03:00 committed by GitHub
parent 54fec7b772
commit f06def7d6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 14 deletions

View File

@ -108,9 +108,9 @@ fn subtract_digit_array(operand_a []u32, operand_b []u32, mut storage []u32) {
shrink_tail_zeros(mut storage)
}
const karatsuba_multiplication_limit = 240
const karatsuba_multiplication_limit = 70
const toom3_multiplication_limit = 10_000
const toom3_multiplication_limit = 360
@[inline]
fn multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u32) {

View File

@ -948,3 +948,9 @@ fn test_integer_from_bytes_ignores_potential_leading_zero_bytes() {
}
}
}
fn test_pow2_is_power_of_2() {
for n in 22000 .. 22010 {
assert big.two_int.pow(n).is_power_of_2(), 'pow2: ${n}'
}
}

View File

@ -164,12 +164,20 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3
// Slices of a and b
a0 := Integer{
digits: unsafe { operand_a[0..k] }
signum: 1
digits: unsafe { operand_a[..k] }
signum: if operand_a[..k].all(it == 0) {
0
} else {
1
}
}
a1 := Integer{
digits: unsafe { operand_a[k..k2] }
signum: 1
signum: if operand_a[k..k2].all(it == 0) {
0
} else {
1
}
}
a2 := Integer{
digits: unsafe { operand_a[k2..] }
@ -187,22 +195,28 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3
signum: 1
}
} else if operand_b.len < k2 {
b0 = Integer{
digits: operand_b[0..k]
signum: 1
if !operand_b[..k].all(it == 0) {
b0 = Integer{
digits: operand_b[..k]
signum: 1
}
}
b1 = Integer{
digits: operand_b[k..]
signum: 1
}
} else {
b0 = Integer{
digits: operand_b[0..k]
signum: 1
if !operand_b[..k].all(it == 0) {
b0 = Integer{
digits: operand_b[..k]
signum: 1
}
}
b1 = Integer{
digits: operand_b[k..k2]
signum: 1
if !operand_b[k..k2].all(it == 0) {
b1 = Integer{
digits: operand_b[k..k2]
signum: 1
}
}
b2 = Integer{
digits: operand_b[k2..]