diff --git a/vlib/math/big/array_ops.v b/vlib/math/big/array_ops.v index 355d4535e5..6b1da19c64 100644 --- a/vlib/math/big/array_ops.v +++ b/vlib/math/big/array_ops.v @@ -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) { diff --git a/vlib/math/big/big_test.v b/vlib/math/big/big_test.v index 12274412c1..ae7e59b34d 100644 --- a/vlib/math/big/big_test.v +++ b/vlib/math/big/big_test.v @@ -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}' + } +} diff --git a/vlib/math/big/special_array_ops.v b/vlib/math/big/special_array_ops.v index 17234a1c2b..f5ffb3ceea 100644 --- a/vlib/math/big/special_array_ops.v +++ b/vlib/math/big/special_array_ops.v @@ -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..]