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

ext/bcmath: Extracted common logic into function and macro (#18103)

This commit is contained in:
Saki Takamachi
2025-03-19 18:10:12 +09:00
committed by GitHub
parent b450a9c826
commit fb07c62f2c
4 changed files with 38 additions and 44 deletions

View File

@@ -85,4 +85,30 @@ static inline void bc_convert_to_vector_with_zero_pad(BC_VECTOR *n_vector, const
bc_convert_to_vector(n_vector, nend, nlen);
}
static inline void bc_convert_vector_to_char(const BC_VECTOR *vector, char *nptr, char *nend, size_t arr_size)
{
size_t i = 0;
while (i < arr_size - 1) {
#if BC_VECTOR_SIZE == 4
bc_write_bcd_representation(vector[i], nend - 3);
nend -= 4;
#else
bc_write_bcd_representation(vector[i] / 10000, nend - 7);
bc_write_bcd_representation(vector[i] % 10000, nend - 3);
nend -= 8;
#endif
i++;
}
/*
* The last digit may carry over.
* Also need to fill it to the end with zeros, so loop until the end of the string.
*/
BC_VECTOR last = vector[i];
while (nend >= nptr) {
*nend-- = last % BASE;
last /= BASE;
}
}
#endif

View File

@@ -255,10 +255,10 @@ static void bc_do_div(
const char *divisor, size_t divisor_size,
bc_num *quot, size_t quot_size
) {
size_t numerator_arr_size = (numerator_size + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t divisor_arr_size = (divisor_size + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t numerator_arr_size = BC_ARR_SIZE_FROM_LEN(numerator_size);
size_t divisor_arr_size = BC_ARR_SIZE_FROM_LEN(divisor_size);
size_t quot_arr_size = numerator_arr_size - divisor_arr_size + 1;
size_t quot_real_arr_size = MIN(quot_arr_size, (quot_size + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE);
size_t quot_real_arr_size = MIN(quot_arr_size, BC_ARR_SIZE_FROM_LEN(quot_size));
BC_VECTOR stack_vectors[BC_STACK_VECTOR_SIZE];
size_t allocation_arr_size = numerator_arr_size + divisor_arr_size + quot_arr_size;
@@ -293,22 +293,7 @@ static void bc_do_div(
char *qptr = (*quot)->n_value;
char *qend = qptr + (*quot)->n_len + (*quot)->n_scale - 1;
size_t i;
for (i = 0; i < quot_real_arr_size - 1; i++) {
#if BC_VECTOR_SIZE == 4
bc_write_bcd_representation(quot_vectors[i], qend - 3);
qend -= 4;
#else
bc_write_bcd_representation(quot_vectors[i] / 10000, qend - 7);
bc_write_bcd_representation(quot_vectors[i] % 10000, qend - 3);
qend -= 8;
#endif
}
while (qend >= qptr) {
*qend-- = quot_vectors[i] % BASE;
quot_vectors[i] /= BASE;
}
bc_convert_vector_to_char(quot_vectors, qptr, qend, quot_real_arr_size);
if (allocation_arr_size > BC_STACK_VECTOR_SIZE) {
efree(numerator_vectors);

View File

@@ -67,6 +67,8 @@
/* 64-bytes for 64-bit */
#define BC_STACK_VECTOR_SIZE 8
#define BC_ARR_SIZE_FROM_LEN(len) (((len) + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE)
/*
* Adding more than this many times may cause uint32_t/uint64_t to overflow.
* Typically this is 1844 for 64bit and 42 for 32bit.

View File

@@ -107,27 +107,8 @@ static inline void bc_mul_finish_from_vector(BC_VECTOR *prod_vector, size_t prod
*prod = bc_new_num_nonzeroed(prodlen, 0);
char *pptr = (*prod)->n_value;
char *pend = pptr + prodlen - 1;
size_t i = 0;
while (i < prod_arr_size - 1) {
#if BC_VECTOR_SIZE == 4
bc_write_bcd_representation(prod_vector[i], pend - 3);
pend -= 4;
#else
bc_write_bcd_representation(prod_vector[i] / 10000, pend - 7);
bc_write_bcd_representation(prod_vector[i] % 10000, pend - 3);
pend -= 8;
#endif
i++;
}
/*
* The last digit may carry over.
* Also need to fill it to the end with zeros, so loop until the end of the string.
*/
while (pend >= pptr) {
*pend-- = prod_vector[i] % BASE;
prod_vector[i] /= BASE;
}
bc_convert_vector_to_char(prod_vector, pptr, pend, prod_arr_size);
}
/*
@@ -145,9 +126,9 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
const char *n2end = n2->n_value + n2len - 1;
size_t prodlen = n1len + n2len;
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 = (prodlen + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t n1_arr_size = BC_ARR_SIZE_FROM_LEN(n1len);
size_t n2_arr_size = BC_ARR_SIZE_FROM_LEN(n2len);
size_t prod_arr_size = BC_ARR_SIZE_FROM_LEN(prodlen);
BC_VECTOR stack_vectors[BC_STACK_VECTOR_SIZE];
size_t allocation_arr_size = n1_arr_size + n2_arr_size + prod_arr_size;
@@ -206,8 +187,8 @@ static void bc_standard_square(bc_num n1, size_t n1len, bc_num *prod)
const char *n1end = n1->n_value + n1len - 1;
size_t prodlen = n1len + n1len;
size_t n1_arr_size = (n1len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t prod_arr_size = (prodlen + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t n1_arr_size = BC_ARR_SIZE_FROM_LEN(n1len);
size_t prod_arr_size = BC_ARR_SIZE_FROM_LEN(prodlen);
BC_VECTOR *buf = safe_emalloc(n1_arr_size + n1_arr_size + prod_arr_size, sizeof(BC_VECTOR), 0);