From a0ccdb08ba5cff960a54882734be99a62e39e0eb Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Tue, 18 Mar 2025 10:42:30 +0900 Subject: [PATCH 1/3] Added `bc_convert_vector_to_char()` --- ext/bcmath/libbcmath/src/convert.h | 25 +++++++++++++++++++++++++ ext/bcmath/libbcmath/src/div.c | 17 +---------------- ext/bcmath/libbcmath/src/recmul.c | 21 +-------------------- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/ext/bcmath/libbcmath/src/convert.h b/ext/bcmath/libbcmath/src/convert.h index e278ae5fef1aa..787fe1bf1a984 100644 --- a/ext/bcmath/libbcmath/src/convert.h +++ b/ext/bcmath/libbcmath/src/convert.h @@ -85,4 +85,29 @@ 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(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. + */ + while (nend >= nptr) { + *nend-- = vector[i] % BASE; + vector[i] /= BASE; + } +} + #endif diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 7da023df9a7e4..7e4465e49a60f 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -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); diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index fc7efb37ebf02..5dae60415ef17 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -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); } /* From a714f9fd6e900b52d2a937542df45f25005f9579 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Tue, 18 Mar 2025 11:33:12 +0900 Subject: [PATCH 2/3] Added `BC_ARR_SIZE_FROM_LEN` --- ext/bcmath/libbcmath/src/div.c | 6 +++--- ext/bcmath/libbcmath/src/private.h | 2 ++ ext/bcmath/libbcmath/src/recmul.c | 10 +++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 7e4465e49a60f..1cf8a434c8608 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -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; diff --git a/ext/bcmath/libbcmath/src/private.h b/ext/bcmath/libbcmath/src/private.h index 7e972952c75e3..91facfb2f8b40 100644 --- a/ext/bcmath/libbcmath/src/private.h +++ b/ext/bcmath/libbcmath/src/private.h @@ -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. diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 5dae60415ef17..26ce1641db410 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -126,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; @@ -187,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); From cf98eb13a8cf9bc28eebecea6ceec828ad9df073 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Wed, 19 Mar 2025 11:22:05 +0900 Subject: [PATCH 3/3] `BC_VECTOR *vector` to const --- ext/bcmath/libbcmath/src/convert.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ext/bcmath/libbcmath/src/convert.h b/ext/bcmath/libbcmath/src/convert.h index 787fe1bf1a984..73c38cd130107 100644 --- a/ext/bcmath/libbcmath/src/convert.h +++ b/ext/bcmath/libbcmath/src/convert.h @@ -85,7 +85,7 @@ 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(BC_VECTOR *vector, char *nptr, char *nend, size_t arr_size) +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) { @@ -104,9 +104,10 @@ static inline void bc_convert_vector_to_char(BC_VECTOR *vector, char *nptr, char * 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-- = vector[i] % BASE; - vector[i] /= BASE; + *nend-- = last % BASE; + last /= BASE; } }