From 3ff726ae0ca3c632b89f94d2171f3afe41118399 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 16 Mar 2025 19:56:51 +0900 Subject: [PATCH 01/14] Removed `bc_fast_square` and `bc_standard_square`. --- ext/bcmath/libbcmath/src/recmul.c | 71 ------------------------------- 1 file changed, 71 deletions(-) diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 26ce1641db410..c405d006c0f27 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -72,28 +72,6 @@ static inline void bc_fast_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, } } -/* - * Equivalent of bc_fast_mul for small numbers to perform computations - * without using array. - */ -static inline void bc_fast_square(bc_num n1, size_t n1len, bc_num *prod) -{ - const char *n1end = n1->n_value + n1len - 1; - - BC_VECTOR n1_vector = bc_partial_convert_to_vector(n1end, n1len); - BC_VECTOR prod_vector = n1_vector * n1_vector; - - size_t prodlen = n1len + n1len; - *prod = bc_new_num_nonzeroed(prodlen, 0); - char *pptr = (*prod)->n_value; - char *pend = pptr + prodlen - 1; - - while (pend >= pptr) { - *pend-- = prod_vector % BASE; - prod_vector /= BASE; - } -} - /* Common part of functions bc_standard_mul and bc_standard_square * that takes a vector and converts it to a bc_num */ static inline void bc_mul_finish_from_vector(BC_VECTOR *prod_vector, size_t prod_arr_size, size_t prodlen, bc_num *prod) { @@ -180,55 +158,6 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc } } -/** This is bc_standard_mul implementation for square */ -static void bc_standard_square(bc_num n1, size_t n1len, bc_num *prod) -{ - size_t i; - const char *n1end = n1->n_value + n1len - 1; - size_t prodlen = n1len + n1len; - - 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); - - BC_VECTOR *n1_vector = buf; - BC_VECTOR *prod_vector = n1_vector + n1_arr_size + n1_arr_size; - - for (i = 0; i < prod_arr_size; i++) { - prod_vector[i] = 0; - } - - /* Convert to BC_VECTOR[] */ - bc_convert_to_vector(n1_vector, n1end, n1len); - - /* Multiplication and addition */ - size_t count = 0; - for (i = 0; i < n1_arr_size; i++) { - /* - * This calculation adds the result multiple times to the array entries. - * When multiplying large numbers of digits, there is a possibility of - * overflow, so digit adjustment is performed beforehand. - */ - if (UNEXPECTED(count >= BC_VECTOR_NO_OVERFLOW_ADD_COUNT)) { - bc_mul_carry_calc(prod_vector, prod_arr_size); - count = 0; - } - count++; - for (size_t j = 0; j < n1_arr_size; j++) { - prod_vector[i + j] += n1_vector[i] * n1_vector[j]; - } - } - - bc_mul_finish_from_vector(prod_vector, prod_arr_size, prodlen, prod); - - efree(buf); -} - -/* The multiply routine. N2 times N1 is put int PROD with the scale of - the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)). - */ - bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale) { bc_num prod; From 788a884a5365a14daa3c9bd9b74317c4fcdf5263 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 16 Mar 2025 19:58:08 +0900 Subject: [PATCH 02/14] Merged `bc_mul_finish_from_vector` into `bc_standard_mul` --- ext/bcmath/libbcmath/src/recmul.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index c405d006c0f27..b12dccd5f5615 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -72,23 +72,6 @@ static inline void bc_fast_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, } } -/* Common part of functions bc_standard_mul and bc_standard_square - * that takes a vector and converts it to a bc_num */ -static inline void bc_mul_finish_from_vector(BC_VECTOR *prod_vector, size_t prod_arr_size, size_t prodlen, bc_num *prod) { - /* - * Move a value exceeding 4/8 digits by carrying to the next digit. - * However, the last digit does nothing. - */ - bc_mul_carry_calc(prod_vector, prod_arr_size); - - /* Convert to bc_num */ - *prod = bc_new_num_nonzeroed(prodlen, 0); - char *pptr = (*prod)->n_value; - char *pend = pptr + prodlen - 1; - - bc_convert_vector_to_char(prod_vector, pptr, pend, prod_arr_size); -} - /* * Converts the BCD of bc_num by 4 (32 bits) or 8 (64 bits) digits to an array of BC_VECTOR. * The array is generated starting with the smaller digits. @@ -151,7 +134,17 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc } } - bc_mul_finish_from_vector(prod_vector, prod_arr_size, prodlen, prod); + /* + * Move a value exceeding 4/8 digits by carrying to the next digit. + * However, the last digit does nothing. + */ + bc_mul_carry_calc(prod_vector, prod_arr_size); + + /* Convert to bc_num */ + *prod = bc_new_num_nonzeroed(prodlen, 0); + char *pptr = (*prod)->n_value; + char *pend = pptr + prodlen - 1; + bc_convert_vector_to_char(prod_vector, pptr, pend, prod_arr_size); if (allocation_arr_size > BC_STACK_VECTOR_SIZE) { efree(n1_vector); From 186214b29917a16f3b10b1f04b5dd58673854347 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 16 Mar 2025 20:01:29 +0900 Subject: [PATCH 03/14] The calculation process of BC_VECTOR was separated inline as `bc_standard_vector_mul`. --- ext/bcmath/libbcmath/src/recmul.c | 62 +++++++++++++++++-------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index b12dccd5f5615..6db9c7b175d6e 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -72,6 +72,38 @@ static inline void bc_fast_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, } } +static inline void bc_standard_vector_mul( + BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size) +{ + for (size_t i = 0; i < prod_arr_size; i++) { + prod_vector[i] = 0; + } + + /* Multiplication and addition */ + size_t count = 0; + for (size_t i = 0; i < n1_arr_size; i++) { + /* + * This calculation adds the result multiple times to the array entries. + * When multiplying large numbers of digits, there is a possibility of + * overflow, so digit adjustment is performed beforehand. + */ + if (UNEXPECTED(count >= BC_VECTOR_NO_OVERFLOW_ADD_COUNT)) { + bc_mul_carry_calc(prod_vector, prod_arr_size); + count = 0; + } + count++; + for (size_t j = 0; j < n2_arr_size; j++) { + prod_vector[i + j] += n1_vector[i] * n2_vector[j]; + } + } + + /* + * Move a value exceeding 4/8 digits by carrying to the next digit. + * However, the last digit does nothing. + */ + bc_mul_carry_calc(prod_vector, prod_arr_size); +} + /* * Converts the BCD of bc_num by 4 (32 bits) or 8 (64 bits) digits to an array of BC_VECTOR. * The array is generated starting with the smaller digits. @@ -82,7 +114,6 @@ static inline void bc_fast_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, */ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc_num *prod) { - size_t i; const char *n1end = n1->n_value + n1len - 1; const char *n2end = n2->n_value + n2len - 1; size_t prodlen = n1len + n2len; @@ -108,37 +139,12 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc BC_VECTOR *n2_vector = n1_vector + n1_arr_size; BC_VECTOR *prod_vector = n2_vector + n2_arr_size; - for (i = 0; i < prod_arr_size; i++) { - prod_vector[i] = 0; - } - /* Convert to BC_VECTOR[] */ bc_convert_to_vector(n1_vector, n1end, n1len); bc_convert_to_vector(n2_vector, n2end, n2len); - /* Multiplication and addition */ - size_t count = 0; - for (i = 0; i < n1_arr_size; i++) { - /* - * This calculation adds the result multiple times to the array entries. - * When multiplying large numbers of digits, there is a possibility of - * overflow, so digit adjustment is performed beforehand. - */ - if (UNEXPECTED(count >= BC_VECTOR_NO_OVERFLOW_ADD_COUNT)) { - bc_mul_carry_calc(prod_vector, prod_arr_size); - count = 0; - } - count++; - for (size_t j = 0; j < n2_arr_size; j++) { - prod_vector[i + j] += n1_vector[i] * n2_vector[j]; - } - } - - /* - * Move a value exceeding 4/8 digits by carrying to the next digit. - * However, the last digit does nothing. - */ - bc_mul_carry_calc(prod_vector, prod_arr_size); + /* Do multiply */ + bc_standard_vector_mul(n1_vector, n1_arr_size, n2_vector, n2_arr_size, prod_vector, prod_arr_size); /* Convert to bc_num */ *prod = bc_new_num_nonzeroed(prodlen, 0); From c1568f152a602659bc71b430d29137f6fafac55c Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 16 Mar 2025 20:02:50 +0900 Subject: [PATCH 04/14] Removed the conversion process of bc_num and BC_VECTOR from `bc_square`, and renamed to `bc_square_vector`. --- ext/bcmath/libbcmath/src/bcmath.h | 2 -- ext/bcmath/libbcmath/src/private.h | 1 + ext/bcmath/libbcmath/src/recmul.c | 25 ++++++++----------------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 1f05ad51f7f26..3a0b80dfc6893 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -147,8 +147,6 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale); *(result) = mul_ex; \ } while (0) -bc_num bc_square(bc_num n1, size_t scale); - bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, size_t scale); bool bc_modulo(bc_num num1, bc_num num2, bc_num *resul, size_t scale); diff --git a/ext/bcmath/libbcmath/src/private.h b/ext/bcmath/libbcmath/src/private.h index 91facfb2f8b40..59f3f92a334d0 100644 --- a/ext/bcmath/libbcmath/src/private.h +++ b/ext/bcmath/libbcmath/src/private.h @@ -84,6 +84,7 @@ static const BC_VECTOR BC_POW_10_LUT[9] = { bcmath_compare_result _bc_do_compare (bc_num n1, bc_num n2, size_t scale, bool use_sign); bc_num _bc_do_add (bc_num n1, bc_num n2); bc_num _bc_do_sub (bc_num n1, bc_num n2); +void bc_square_vector(BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size); void _bc_rm_leading_zeros (bc_num num); #endif diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 6db9c7b175d6e..7c971a0a038e8 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -186,24 +186,15 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale) return prod; } -bc_num bc_square(bc_num n1, size_t scale) +void bc_square_vector(BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size) { - bc_num prod; - - size_t len1 = n1->n_len + n1->n_scale; - size_t full_scale = n1->n_scale + n1->n_scale; - size_t prod_scale = MIN(full_scale, MAX(scale, n1->n_scale)); - - if (len1 <= BC_VECTOR_SIZE) { - bc_fast_square(n1, len1, &prod); + if (n1_arr_size == 1) { + prod_vector[0] = *n1_vector * *n1_vector; + if (prod_arr_size == 2) { + prod_vector[1] = prod_vector[0] / BC_VECTOR_BOUNDARY_NUM; + prod_vector[0] %= BC_VECTOR_BOUNDARY_NUM; + } } else { - bc_standard_square(n1, len1, &prod); + bc_standard_vector_mul(n1_vector, n1_arr_size, n1_vector, n1_arr_size, prod_vector, prod_arr_size); } - - prod->n_sign = PLUS; - prod->n_len -= full_scale; - prod->n_scale = prod_scale; - _bc_rm_leading_zeros(prod); - - return prod; } From a42d2e1e1e8746a55c230f21e6422403a6d735b5 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Mon, 17 Mar 2025 11:24:05 +0900 Subject: [PATCH 05/14] Changed bc_square_vector to normal multiplication and renamed it to bc_multiply_vector --- ext/bcmath/libbcmath/src/private.h | 3 ++- ext/bcmath/libbcmath/src/recmul.c | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ext/bcmath/libbcmath/src/private.h b/ext/bcmath/libbcmath/src/private.h index 59f3f92a334d0..327a72c3677af 100644 --- a/ext/bcmath/libbcmath/src/private.h +++ b/ext/bcmath/libbcmath/src/private.h @@ -84,7 +84,8 @@ static const BC_VECTOR BC_POW_10_LUT[9] = { bcmath_compare_result _bc_do_compare (bc_num n1, bc_num n2, size_t scale, bool use_sign); bc_num _bc_do_add (bc_num n1, bc_num n2); bc_num _bc_do_sub (bc_num n1, bc_num n2); -void bc_square_vector(BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size); +void bc_multiply_vector( + BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size); void _bc_rm_leading_zeros (bc_num num); #endif diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 7c971a0a038e8..64934cd4c3217 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -186,15 +186,16 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale) return prod; } -void bc_square_vector(BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size) +void bc_multiply_vector( + BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size) { - if (n1_arr_size == 1) { - prod_vector[0] = *n1_vector * *n1_vector; + if (n1_arr_size == 1 && n2_arr_size == 1) { + prod_vector[0] = *n1_vector * *n2_vector; if (prod_arr_size == 2) { prod_vector[1] = prod_vector[0] / BC_VECTOR_BOUNDARY_NUM; prod_vector[0] %= BC_VECTOR_BOUNDARY_NUM; } } else { - bc_standard_vector_mul(n1_vector, n1_arr_size, n1_vector, n1_arr_size, prod_vector, prod_arr_size); + bc_standard_vector_mul(n1_vector, n1_arr_size, n2_vector, n2_arr_size, prod_vector, prod_arr_size); } } From f303d7dfd2f55d1da81be9ce978c87d50ec72bbd Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Mon, 17 Mar 2025 19:54:49 +0900 Subject: [PATCH 06/14] If base is 0, return early. --- ext/bcmath/libbcmath/src/raise.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 1e283864694b6..b658d1579a3ce 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -67,6 +67,13 @@ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { rscale = MIN (base->n_scale * exponent, MAX(scale, base->n_scale)); } + if (bc_is_zero(base)) { + bc_free_num(result); + *result = bc_copy_num(BCG(_zero_)); + /* If the exponent is negative, it divides by 0, so it is false. */ + return !is_neg; + } + /* Set initial value of temp. */ power = bc_copy_num(base); pwrscale = base->n_scale; From 757e3bc5830f7ec39eb759925e9082a99cdf7c6b Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 23 Mar 2025 21:33:54 +0900 Subject: [PATCH 07/14] optimized bc_raise --- ext/bcmath/libbcmath/src/raise.c | 194 ++++++++++++++++++++++++++----- 1 file changed, 163 insertions(+), 31 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index b658d1579a3ce..f9d9dacc35d1f 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -30,24 +30,152 @@ *************************************************************************/ #include "bcmath.h" +#include "convert.h" +#include "private.h" #include #include #include -void bc_square_ex(bc_num n1, bc_num *result, size_t scale_min) { - bc_num square_ex = bc_square(n1, scale_min); - bc_free_num(result); - *(result) = square_ex; +static inline size_t bc_multiply_vector_ex( + BC_VECTOR **n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR **result_vector) +{ + size_t result_arr_size = n1_arr_size + n2_arr_size; + bc_multiply_vector(*n1_vector, n1_arr_size, n2_vector, n2_arr_size, *result_vector, result_arr_size); + + /* Eliminate extra zeros because they increase the number of calculations. */ + while ((*result_vector)[result_arr_size - 1] == 0) { + result_arr_size--; + } + + /* Swap n1_vector and result_vector. */ + BC_VECTOR *tmp = *n1_vector; + *n1_vector = *result_vector; + *result_vector = tmp; + + return result_arr_size; +} + +static inline size_t bc_square_vector_ex(BC_VECTOR **base_vector, size_t base_arr_size, BC_VECTOR **result_vector) +{ + return bc_multiply_vector_ex(base_vector, base_arr_size, *base_vector, base_arr_size, result_vector); +} + +/* Use "exponentiation by squaring". This is the fast path when the results are small. */ +static inline bc_num bc_fast_raise( + const char *base_end, long exponent, size_t base_len, size_t power_len, size_t power_scale, size_t power_full_len) +{ + BC_VECTOR base_vector = 0; + + /* Convert to BC_VECTOR[] */ + bc_convert_to_vector(&base_vector, base_end, base_len); + + while ((exponent & 1) == 0) { + base_vector *= base_vector; + exponent >>= 1; + } + + /* copy base to power */ + BC_VECTOR power_vector = base_vector; + exponent >>= 1; + + while (exponent > 0) { + base_vector *= base_vector; + if ((exponent & 1) == 1) { + power_vector *= base_vector; + } + exponent >>= 1; + } + + bc_num power = bc_new_num_nonzeroed(power_len, power_scale); + char *pptr = power->n_value; + char *pend = pptr + power_full_len - 1; + + while (pend >= pptr) { + *pend-- = power_vector % BASE; + power_vector /= BASE; + } + return power; +} + +/* Use "exponentiation by squaring". This is the standard path. */ +static bc_num bc_standard_raise( + const char *base_ptr, const char *base_end, long exponent, size_t base_len, size_t power_scale) +{ + /* Remove the leading zeros as they will be filled in later. */ + while (*base_ptr++ == 0) { + base_len--; + } + + size_t base_arr_size = BC_ARR_SIZE_FROM_LEN(base_len); + size_t max_power_arr_size = base_arr_size * exponent; + + /* The allocated memory area is reused on a rotational basis, so the same size is required. */ + BC_VECTOR *buf = safe_emalloc(max_power_arr_size * 3, sizeof(BC_VECTOR), 0); + BC_VECTOR *base_vector = buf; + BC_VECTOR *power_vector = base_vector + max_power_arr_size; + BC_VECTOR *tmp_result_vector = power_vector + max_power_arr_size; + + /* Convert to BC_VECTOR[] */ + bc_convert_to_vector(base_vector, base_end, base_len); + + while ((exponent & 1) == 0) { + base_arr_size = bc_square_vector_ex(&base_vector, base_arr_size, &tmp_result_vector); + exponent >>= 1; + } + + /* copy base to power */ + size_t power_arr_size = base_arr_size; + for (size_t i = 0; i < base_arr_size; i++) { + power_vector[i] = base_vector[i]; + } + exponent >>= 1; + + while (exponent > 0) { + base_arr_size = bc_square_vector_ex(&base_vector, base_arr_size, &tmp_result_vector); + if ((exponent & 1) == 1) { + power_arr_size = bc_multiply_vector_ex(&power_vector, power_arr_size, base_vector, base_arr_size, &tmp_result_vector); + } + exponent >>= 1; + } + + /* Convert to bc_num */ + size_t power_leading_zeros = 0; + size_t power_len; + size_t power_full_len = power_arr_size * BC_VECTOR_SIZE; + if (power_full_len > power_scale) { + power_len = power_full_len - power_scale; + } else { + power_len = 1; + power_leading_zeros = power_scale - power_full_len + 1; + power_full_len = power_scale + 1; + } + bc_num power = bc_new_num_nonzeroed(power_len, power_scale); + + char *pptr = power->n_value; + char *pend = pptr + power_full_len - 1; + + /* Pad with leading zeros if necessary. */ + while (power_leading_zeros > sizeof(uint32_t)) { + bc_write_bcd_representation(0, pptr); + pptr += sizeof(uint32_t); + power_leading_zeros -= sizeof(uint32_t); + } + for (size_t i = 0; i < power_leading_zeros; i++) { + *pptr++ = 0; + } + + bc_convert_vector_to_char(power_vector, pptr, pend, power_arr_size); + + efree(buf); + + return power; } /* Raise "base" to the "exponent" power. The result is placed in RESULT. Maximum exponent is LONG_MAX. If a "exponent" is not an integer, only the integer part is used. */ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { - bc_num temp, power; size_t rscale; - size_t pwrscale; - size_t calcscale; bool is_neg; /* Special case if exponent is a zero. */ @@ -74,43 +202,47 @@ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { return !is_neg; } - /* Set initial value of temp. */ - power = bc_copy_num(base); - pwrscale = base->n_scale; - while ((exponent & 1) == 0) { - pwrscale = 2 * pwrscale; - bc_square_ex(power, &power, pwrscale); - exponent = exponent >> 1; + size_t base_len = base->n_len + base->n_scale; + size_t power_len = base->n_len * exponent; + size_t power_scale = base->n_scale * exponent; + size_t power_full_len = power_len + power_scale; + + sign power_sign; + if (base->n_sign == MINUS && (exponent & 1) == 1) { + power_sign = MINUS; + } else { + power_sign = PLUS; } - temp = bc_copy_num(power); - calcscale = pwrscale; - exponent = exponent >> 1; - /* Do the calculation. */ - while (exponent > 0) { - pwrscale = 2 * pwrscale; - bc_square_ex(power, &power, pwrscale); - if ((exponent & 1) == 1) { - calcscale = pwrscale + calcscale; - bc_multiply_ex(temp, power, &temp, calcscale); - } - exponent = exponent >> 1; + const char *base_end = base->n_value + base_len - 1; + + bc_num power; + if (base_len <= BC_VECTOR_SIZE && power_full_len <= BC_VECTOR_SIZE * 2) { + power = bc_fast_raise(base_end, exponent, base_len, power_len, power_scale, power_full_len); + } else { + power = bc_standard_raise(base->n_value, base_end, exponent, base_len, power_scale); + } + + _bc_rm_leading_zeros(power); + if (bc_is_zero(power)) { + power->n_sign = PLUS; + power->n_scale = 0; + } else { + power->n_sign = power_sign; } /* Assign the value. */ if (is_neg) { - if (bc_divide(BCG(_one_), temp, result, rscale) == false) { - bc_free_num (&temp); + if (bc_divide(BCG(_one_), power, result, rscale) == false) { bc_free_num (&power); return false; } - bc_free_num (&temp); + bc_free_num (&power); } else { bc_free_num (result); - *result = temp; + *result = power; (*result)->n_scale = MIN(scale, (*result)->n_scale); } - bc_free_num (&power); return true; } From d203371138b64183e2e770f6de671631bd578e55 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sat, 19 Apr 2025 14:18:22 +0900 Subject: [PATCH 08/14] Use const appropriately --- ext/bcmath/libbcmath/src/private.h | 3 ++- ext/bcmath/libbcmath/src/recmul.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ext/bcmath/libbcmath/src/private.h b/ext/bcmath/libbcmath/src/private.h index 327a72c3677af..de9045a16c7e5 100644 --- a/ext/bcmath/libbcmath/src/private.h +++ b/ext/bcmath/libbcmath/src/private.h @@ -85,7 +85,8 @@ bcmath_compare_result _bc_do_compare (bc_num n1, bc_num n2, size_t scale, bool u bc_num _bc_do_add (bc_num n1, bc_num n2); bc_num _bc_do_sub (bc_num n1, bc_num n2); void bc_multiply_vector( - BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size); + const BC_VECTOR *n1_vector, size_t n1_arr_size, const BC_VECTOR *n2_vector, size_t n2_arr_size, + BC_VECTOR *prod_vector, size_t prod_arr_size); void _bc_rm_leading_zeros (bc_num num); #endif diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 64934cd4c3217..5e69fd7eb0336 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -73,7 +73,8 @@ static inline void bc_fast_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, } static inline void bc_standard_vector_mul( - BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size) + const BC_VECTOR *n1_vector, size_t n1_arr_size, const BC_VECTOR *n2_vector, size_t n2_arr_size, + BC_VECTOR *prod_vector, size_t prod_arr_size) { for (size_t i = 0; i < prod_arr_size; i++) { prod_vector[i] = 0; @@ -187,7 +188,8 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale) } void bc_multiply_vector( - BC_VECTOR *n1_vector, size_t n1_arr_size, BC_VECTOR *n2_vector, size_t n2_arr_size, BC_VECTOR *prod_vector, size_t prod_arr_size) + const BC_VECTOR *n1_vector, size_t n1_arr_size, const BC_VECTOR *n2_vector, size_t n2_arr_size, + BC_VECTOR *prod_vector, size_t prod_arr_size) { if (n1_arr_size == 1 && n2_arr_size == 1) { prod_vector[0] = *n1_vector * *n2_vector; From 255695126765c4046385a3ee1c73ccc526f1ff8a Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 27 Apr 2025 14:05:36 +0900 Subject: [PATCH 09/14] Address comments --- ext/bcmath/libbcmath/src/raise.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index f9d9dacc35d1f..2cd869c39a06d 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -102,7 +102,8 @@ static bc_num bc_standard_raise( const char *base_ptr, const char *base_end, long exponent, size_t base_len, size_t power_scale) { /* Remove the leading zeros as they will be filled in later. */ - while (*base_ptr++ == 0) { + while (*base_ptr == 0) { + base_ptr++; base_len--; } @@ -110,7 +111,7 @@ static bc_num bc_standard_raise( size_t max_power_arr_size = base_arr_size * exponent; /* The allocated memory area is reused on a rotational basis, so the same size is required. */ - BC_VECTOR *buf = safe_emalloc(max_power_arr_size * 3, sizeof(BC_VECTOR), 0); + BC_VECTOR *buf = safe_emalloc(max_power_arr_size, sizeof(BC_VECTOR) * 3, 0); BC_VECTOR *base_vector = buf; BC_VECTOR *power_vector = base_vector + max_power_arr_size; BC_VECTOR *tmp_result_vector = power_vector + max_power_arr_size; @@ -155,14 +156,8 @@ static bc_num bc_standard_raise( char *pend = pptr + power_full_len - 1; /* Pad with leading zeros if necessary. */ - while (power_leading_zeros > sizeof(uint32_t)) { - bc_write_bcd_representation(0, pptr); - pptr += sizeof(uint32_t); - power_leading_zeros -= sizeof(uint32_t); - } - for (size_t i = 0; i < power_leading_zeros; i++) { - *pptr++ = 0; - } + memset(pptr, 0, power_leading_zeros); + pptr += power_leading_zeros; bc_convert_vector_to_char(power_vector, pptr, pend, power_arr_size); From b96f2d92b99d18cd8dbffae249915f92fa28df65 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 27 Apr 2025 14:40:42 +0900 Subject: [PATCH 10/14] Added overflow check --- ext/bcmath/bcmath.c | 35 ++++++++++++++++++++++++------- ext/bcmath/libbcmath/src/bcmath.h | 14 ++++++++++++- ext/bcmath/libbcmath/src/raise.c | 32 ++++++++++++++++++++++------ 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 962f839ba83f4..b5a396f862718 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -615,11 +615,19 @@ PHP_FUNCTION(bcpow) goto cleanup; } - if (!bc_raise(first, exponent, &result, scale)) { - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); - goto cleanup; + switch (bc_raise(first, exponent, &result, scale)) { + case BC_RAISE_STATUS_OK: + break; + case BC_RAISE_STATUS_DIVIDE_BY_ZERO: + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); + goto cleanup; + case BC_RAISE_STATUS_LEN_IS_OVERFLOW: + case BC_RAISE_STATUS_SCALE_IS_OVERFLOW: + case BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW: + zend_argument_value_error(2, "exponent is too large, the number of digits overflowed"); + goto cleanup; + EMPTY_SWITCH_DEFAULT_CASE(); } - RETVAL_NEW_STR(bc_num2str_ex(result, scale)); cleanup: { @@ -1144,9 +1152,22 @@ static zend_result bcmath_number_pow_internal( } return FAILURE; } - if (!bc_raise(n1, exponent, ret, *scale)) { - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); - return FAILURE; + switch (bc_raise(n1, exponent, ret, *scale)) { + case BC_RAISE_STATUS_OK: + break; + case BC_RAISE_STATUS_DIVIDE_BY_ZERO: + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); + return FAILURE; + case BC_RAISE_STATUS_LEN_IS_OVERFLOW: + case BC_RAISE_STATUS_SCALE_IS_OVERFLOW: + case BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW: + if (is_op) { + zend_value_error("exponent is too large, the number of digits overflowed"); + } else { + zend_argument_value_error(1, "exponent is too large, the number of digits overflowed"); + } + return FAILURE; + EMPTY_SWITCH_DEFAULT_CASE(); } bc_rm_trailing_zeros(*ret); if (scale_expand) { diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index 3a0b80dfc6893..abcea8b5e7834 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -74,6 +74,10 @@ typedef struct bc_struct { #define MAX(a, b) ((a)>(b)?(a):(b)) #define MIN(a, b) ((a)>(b)?(b):(a)) +#ifndef SIZE_T_MAX +#define SIZE_T_MAX (~((size_t) 0)) +#endif + /* Function Prototypes */ void bc_init_numbers(void); @@ -157,6 +161,14 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor); size_t bc_round(bc_num num, zend_long places, zend_long mode, bc_num *result); +typedef enum { + BC_RAISE_STATUS_OK, + BC_RAISE_STATUS_LEN_IS_OVERFLOW, + BC_RAISE_STATUS_SCALE_IS_OVERFLOW, + BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW, + BC_RAISE_STATUS_DIVIDE_BY_ZERO, +} bc_raise_status; + typedef enum { OK, BASE_HAS_FRACTIONAL, @@ -168,7 +180,7 @@ typedef enum { raise_mod_status bc_raisemod(bc_num base, bc_num exponent, bc_num mod, bc_num *result, size_t scale); -bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale); +bc_raise_status bc_raise(bc_num base, long exponent, bc_num *result, size_t scale); void bc_raise_bc_exponent(bc_num base, bc_num exponent, bc_num *resul, size_t scale); diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 2cd869c39a06d..2617e7a079a04 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -108,6 +108,7 @@ static bc_num bc_standard_raise( } size_t base_arr_size = BC_ARR_SIZE_FROM_LEN(base_len); + /* Since it is guaranteed that base_len * exponent does not overflow, there is no possibility of overflow here. */ size_t max_power_arr_size = base_arr_size * exponent; /* The allocated memory area is reused on a rotational basis, so the same size is required. */ @@ -169,7 +170,7 @@ static bc_num bc_standard_raise( /* Raise "base" to the "exponent" power. The result is placed in RESULT. Maximum exponent is LONG_MAX. If a "exponent" is not an integer, only the integer part is used. */ -bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { +bc_raise_status bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { size_t rscale; bool is_neg; @@ -177,7 +178,7 @@ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { if (exponent == 0) { bc_free_num (result); *result = bc_copy_num(BCG(_one_)); - return true; + return BC_RAISE_STATUS_OK; } /* Other initializations. */ @@ -193,13 +194,32 @@ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { if (bc_is_zero(base)) { bc_free_num(result); *result = bc_copy_num(BCG(_zero_)); - /* If the exponent is negative, it divides by 0, so it is false. */ - return !is_neg; + /* If the exponent is negative, it divides by 0 */ + return is_neg ? BC_RAISE_STATUS_DIVIDE_BY_ZERO : BC_RAISE_STATUS_OK; + } + + /* check overflow */ + if (UNEXPECTED(base->n_len > SIZE_T_MAX / exponent)) { + bc_free_num (result); + *result = bc_copy_num(BCG(_one_)); + return BC_RAISE_STATUS_LEN_IS_OVERFLOW; + } + if (UNEXPECTED(base->n_scale > SIZE_T_MAX / exponent)) { + bc_free_num (result); + *result = bc_copy_num(BCG(_one_)); + return BC_RAISE_STATUS_SCALE_IS_OVERFLOW; } size_t base_len = base->n_len + base->n_scale; size_t power_len = base->n_len * exponent; size_t power_scale = base->n_scale * exponent; + + /* check overflow */ + if (UNEXPECTED(power_len > SIZE_T_MAX - power_scale)) { + bc_free_num (result); + *result = bc_copy_num(BCG(_one_)); + return BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW; + } size_t power_full_len = power_len + power_scale; sign power_sign; @@ -230,7 +250,7 @@ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { if (is_neg) { if (bc_divide(BCG(_one_), power, result, rscale) == false) { bc_free_num (&power); - return false; + return BC_RAISE_STATUS_DIVIDE_BY_ZERO; } bc_free_num (&power); } else { @@ -238,7 +258,7 @@ bool bc_raise(bc_num base, long exponent, bc_num *result, size_t scale) { *result = power; (*result)->n_scale = MIN(scale, (*result)->n_scale); } - return true; + return BC_RAISE_STATUS_OK; } /* This is used internally by BCMath */ From 54729fdcba53972b60144dabe055ff1958afd767 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Mon, 28 Apr 2025 09:14:13 +0900 Subject: [PATCH 11/14] use SIZE_MAX --- ext/bcmath/libbcmath/src/bcmath.h | 4 ---- ext/bcmath/libbcmath/src/raise.c | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index abcea8b5e7834..fa335ae404808 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -74,10 +74,6 @@ typedef struct bc_struct { #define MAX(a, b) ((a)>(b)?(a):(b)) #define MIN(a, b) ((a)>(b)?(b):(a)) -#ifndef SIZE_T_MAX -#define SIZE_T_MAX (~((size_t) 0)) -#endif - /* Function Prototypes */ void bc_init_numbers(void); diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 2617e7a079a04..d7a2295aa41c5 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -199,12 +199,12 @@ bc_raise_status bc_raise(bc_num base, long exponent, bc_num *result, size_t scal } /* check overflow */ - if (UNEXPECTED(base->n_len > SIZE_T_MAX / exponent)) { + if (UNEXPECTED(base->n_len > SIZE_MAX / exponent)) { bc_free_num (result); *result = bc_copy_num(BCG(_one_)); return BC_RAISE_STATUS_LEN_IS_OVERFLOW; } - if (UNEXPECTED(base->n_scale > SIZE_T_MAX / exponent)) { + if (UNEXPECTED(base->n_scale > SIZE_MAX / exponent)) { bc_free_num (result); *result = bc_copy_num(BCG(_one_)); return BC_RAISE_STATUS_SCALE_IS_OVERFLOW; @@ -215,7 +215,7 @@ bc_raise_status bc_raise(bc_num base, long exponent, bc_num *result, size_t scal size_t power_scale = base->n_scale * exponent; /* check overflow */ - if (UNEXPECTED(power_len > SIZE_T_MAX - power_scale)) { + if (UNEXPECTED(power_len > SIZE_MAX - power_scale)) { bc_free_num (result); *result = bc_copy_num(BCG(_one_)); return BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW; From 91e38908c8224645b2f407b90ecfcf75e4660db0 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Mon, 28 Apr 2025 09:15:15 +0900 Subject: [PATCH 12/14] On failure, do nothing with the return value --- ext/bcmath/libbcmath/src/raise.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index d7a2295aa41c5..5df8130c24219 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -192,21 +192,15 @@ bc_raise_status bc_raise(bc_num base, long exponent, bc_num *result, size_t scal } if (bc_is_zero(base)) { - bc_free_num(result); - *result = bc_copy_num(BCG(_zero_)); /* If the exponent is negative, it divides by 0 */ return is_neg ? BC_RAISE_STATUS_DIVIDE_BY_ZERO : BC_RAISE_STATUS_OK; } /* check overflow */ if (UNEXPECTED(base->n_len > SIZE_MAX / exponent)) { - bc_free_num (result); - *result = bc_copy_num(BCG(_one_)); return BC_RAISE_STATUS_LEN_IS_OVERFLOW; } if (UNEXPECTED(base->n_scale > SIZE_MAX / exponent)) { - bc_free_num (result); - *result = bc_copy_num(BCG(_one_)); return BC_RAISE_STATUS_SCALE_IS_OVERFLOW; } @@ -216,8 +210,6 @@ bc_raise_status bc_raise(bc_num base, long exponent, bc_num *result, size_t scal /* check overflow */ if (UNEXPECTED(power_len > SIZE_MAX - power_scale)) { - bc_free_num (result); - *result = bc_copy_num(BCG(_one_)); return BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW; } size_t power_full_len = power_len + power_scale; From 20c93091f64cd7928eafe0f5956156bc5d22319e Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Mon, 28 Apr 2025 09:28:57 +0900 Subject: [PATCH 13/14] Error handling is separated as a static function --- ext/bcmath/bcmath.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index b5a396f862718..3430ea2ab970a 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -179,6 +179,26 @@ static zend_result php_str2num(bc_num *num, const zend_string *str) } /* }}} */ +static void bc_pow_err(raise_mod_status status, uint32_t arg_num) +{ + /* If arg_num is 0, it means it is an op */ + switch (status) { + case BC_RAISE_STATUS_DIVIDE_BY_ZERO: + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); + break; + case BC_RAISE_STATUS_LEN_IS_OVERFLOW: + case BC_RAISE_STATUS_SCALE_IS_OVERFLOW: + case BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW: + if (arg_num == 0) { + zend_value_error("exponent is too large, the number of digits overflowed"); + } else { + zend_argument_value_error(arg_num, "exponent is too large, the number of digits overflowed"); + } + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } +} + /* {{{ Returns the sum of two arbitrary precision numbers */ PHP_FUNCTION(bcadd) { @@ -615,18 +635,10 @@ PHP_FUNCTION(bcpow) goto cleanup; } - switch (bc_raise(first, exponent, &result, scale)) { - case BC_RAISE_STATUS_OK: - break; - case BC_RAISE_STATUS_DIVIDE_BY_ZERO: - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); - goto cleanup; - case BC_RAISE_STATUS_LEN_IS_OVERFLOW: - case BC_RAISE_STATUS_SCALE_IS_OVERFLOW: - case BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW: - zend_argument_value_error(2, "exponent is too large, the number of digits overflowed"); - goto cleanup; - EMPTY_SWITCH_DEFAULT_CASE(); + bc_raise_status ret_status = bc_raise(first, exponent, &result, scale); + if (UNEXPECTED(ret_status != BC_RAISE_STATUS_OK)) { + bc_pow_err(ret_status, 2); + goto cleanup; } RETVAL_NEW_STR(bc_num2str_ex(result, scale)); @@ -1152,22 +1164,10 @@ static zend_result bcmath_number_pow_internal( } return FAILURE; } - switch (bc_raise(n1, exponent, ret, *scale)) { - case BC_RAISE_STATUS_OK: - break; - case BC_RAISE_STATUS_DIVIDE_BY_ZERO: - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Negative power of zero"); - return FAILURE; - case BC_RAISE_STATUS_LEN_IS_OVERFLOW: - case BC_RAISE_STATUS_SCALE_IS_OVERFLOW: - case BC_RAISE_STATUS_FULLLEN_IS_OVERFLOW: - if (is_op) { - zend_value_error("exponent is too large, the number of digits overflowed"); - } else { - zend_argument_value_error(1, "exponent is too large, the number of digits overflowed"); - } - return FAILURE; - EMPTY_SWITCH_DEFAULT_CASE(); + bc_raise_status ret_status = bc_raise(n1, exponent, ret, *scale); + if (UNEXPECTED(ret_status != BC_RAISE_STATUS_OK)) { + bc_pow_err(ret_status, is_op ? 0 : 1); + return FAILURE; } bc_rm_trailing_zeros(*ret); if (scale_expand) { From 9e5c9a45368c8d2a543b89fda60f38507995bfdc Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Mon, 28 Apr 2025 10:20:40 +0900 Subject: [PATCH 14/14] Fixed an error in enum type --- ext/bcmath/bcmath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 3430ea2ab970a..f24cf18f140f9 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -179,7 +179,7 @@ static zend_result php_str2num(bc_num *num, const zend_string *str) } /* }}} */ -static void bc_pow_err(raise_mod_status status, uint32_t arg_num) +static void bc_pow_err(bc_raise_status status, uint32_t arg_num) { /* If arg_num is 0, it means it is an op */ switch (status) {