1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 08:12:21 +01:00

ext/bcmath: Minor fixes to bcmul() (#14564)

The original calculation method for prod_arr_size allowed for some error,
which could have increased the number of simple loops without byte tricks
at the end of the calculation when converting to bc_num.

The new method calculates the size accurately, so the number of loops does
not increase unnecessarily.
This commit is contained in:
Saki Takamachi
2024-06-14 02:20:32 +09:00
committed by GitHub
parent 460b851214
commit 37488d6e01

View File

@@ -56,7 +56,7 @@
/* Multiply utility routines */
static inline void bc_digits_adjustment(BC_VECTOR *prod_vector, size_t prod_arr_size)
static inline void bc_mul_carry_calc(BC_VECTOR *prod_vector, size_t prod_arr_size)
{
for (size_t i = 0; i < prod_arr_size - 1; i++) {
prod_vector[i + 1] += prod_vector[i] / BC_VECTOR_BOUNDARY_NUM;
@@ -237,7 +237,7 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
size_t n1_arr_size = (n1len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t n2_arr_size = (n2len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t prod_arr_size = n1_arr_size + n2_arr_size - 1;
size_t prod_arr_size = (prodlen + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
/*
* let's say that N is the max of n1len and n2len (and a multiple of BC_VECTOR_SIZE for simplicity),
@@ -254,7 +254,7 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
prod_vector[i] = 0;
}
/* Convert to uint[] */
/* Convert to BC_VECTOR[] */
bc_convert_to_vector(n1_vector, n1end, n1len);
bc_convert_to_vector(n2_vector, n2end, n2len);
@@ -267,7 +267,7 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
* overflow, so digit adjustment is performed beforehand.
*/
if (UNEXPECTED(count >= BC_VECTOR_NO_OVERFLOW_ADD_COUNT)) {
bc_digits_adjustment(prod_vector, prod_arr_size);
bc_mul_carry_calc(prod_vector, prod_arr_size);
count = 0;
}
count++;
@@ -280,7 +280,7 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
* Move a value exceeding 4/8 digits by carrying to the next digit.
* However, the last digit does nothing.
*/
bc_digits_adjustment(prod_vector, prod_arr_size);
bc_mul_carry_calc(prod_vector, prod_arr_size);
/* Convert to bc_num */
*prod = bc_new_num_nonzeroed(prodlen, 0);