mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Avoid unnecessary destruction in bc_mul()
This commit is contained in:
parent
0cd952d851
commit
34b2116eb5
8 changed files with 21 additions and 18 deletions
|
@ -242,7 +242,7 @@ PHP_FUNCTION(bcmul)
|
||||||
zend_string *left, *right;
|
zend_string *left, *right;
|
||||||
zend_long scale_param;
|
zend_long scale_param;
|
||||||
bool scale_param_is_null = 1;
|
bool scale_param_is_null = 1;
|
||||||
bc_num first = NULL, second = NULL, result;
|
bc_num first = NULL, second = NULL, result = NULL;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
ZEND_PARSE_PARAMETERS_START(2, 3)
|
ZEND_PARSE_PARAMETERS_START(2, 3)
|
||||||
|
@ -261,8 +261,6 @@ PHP_FUNCTION(bcmul)
|
||||||
scale = (int) scale_param;
|
scale = (int) scale_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
bc_init_num(&result);
|
|
||||||
|
|
||||||
if (php_str2num(&first, ZSTR_VAL(left)) == FAILURE) {
|
if (php_str2num(&first, ZSTR_VAL(left)) == FAILURE) {
|
||||||
zend_argument_value_error(1, "is not well-formed");
|
zend_argument_value_error(1, "is not well-formed");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -273,7 +271,7 @@ PHP_FUNCTION(bcmul)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
bc_multiply (first, second, &result, scale);
|
result = bc_multiply (first, second, scale);
|
||||||
|
|
||||||
RETVAL_NEW_STR(bc_num2str_ex(result, scale));
|
RETVAL_NEW_STR(bc_num2str_ex(result, scale));
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,13 @@ bc_num bc_sub(bc_num n1, bc_num n2, size_t scale_min);
|
||||||
*(result) = sub_ex; \
|
*(result) = sub_ex; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale);
|
bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale);
|
||||||
|
|
||||||
|
#define bc_multiply_ex(n1, n2, result, scale_min) do { \
|
||||||
|
bc_num mul_ex = bc_multiply(n1, n2, scale_min); \
|
||||||
|
bc_free_num (result); \
|
||||||
|
*(result) = mul_ex; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale);
|
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, size_t scale
|
||||||
if (quot) {
|
if (quot) {
|
||||||
quotient = bc_copy_num(temp);
|
quotient = bc_copy_num(temp);
|
||||||
}
|
}
|
||||||
bc_multiply(temp, num2, &temp, rscale);
|
bc_multiply_ex(temp, num2, &temp, rscale);
|
||||||
bc_sub_ex(num1, temp, rem, rscale);
|
bc_sub_ex(num1, temp, rem, rscale);
|
||||||
bc_free_num (&temp);
|
bc_free_num (&temp);
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ void bc_out_num(bc_num num, int o_base, void (*out_char)(char), bool leading_zer
|
||||||
pre_space = false;
|
pre_space = false;
|
||||||
t_num = bc_copy_num(BCG(_one_));
|
t_num = bc_copy_num(BCG(_one_));
|
||||||
while (t_num->n_len <= num->n_scale) {
|
while (t_num->n_len <= num->n_scale) {
|
||||||
bc_multiply(frac_part, base, &frac_part, num->n_scale);
|
bc_multiply_ex(frac_part, base, &frac_part, num->n_scale);
|
||||||
fdigit = bc_num2long(frac_part);
|
fdigit = bc_num2long(frac_part);
|
||||||
bc_int2num(&int_part, fdigit);
|
bc_int2num(&int_part, fdigit);
|
||||||
bc_sub_ex(frac_part, int_part, &frac_part, 0);
|
bc_sub_ex(frac_part, int_part, &frac_part, 0);
|
||||||
|
@ -172,7 +172,7 @@ void bc_out_num(bc_num num, int o_base, void (*out_char)(char), bool leading_zer
|
||||||
bc_out_long(fdigit, max_o_digit->n_len, pre_space, out_char);
|
bc_out_long(fdigit, max_o_digit->n_len, pre_space, out_char);
|
||||||
pre_space = true;
|
pre_space = true;
|
||||||
}
|
}
|
||||||
bc_multiply(t_num, base, &t_num, 0);
|
bc_multiply_ex(t_num, base, &t_num, 0);
|
||||||
}
|
}
|
||||||
bc_free_num (&t_num);
|
bc_free_num (&t_num);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ void bc_raise(bc_num num1, long exponent, bc_num *result, size_t scale)
|
||||||
pwrscale = num1->n_scale;
|
pwrscale = num1->n_scale;
|
||||||
while ((exponent & 1) == 0) {
|
while ((exponent & 1) == 0) {
|
||||||
pwrscale = 2 * pwrscale;
|
pwrscale = 2 * pwrscale;
|
||||||
bc_multiply(power, power, &power, pwrscale);
|
bc_multiply_ex(power, power, &power, pwrscale);
|
||||||
exponent = exponent >> 1;
|
exponent = exponent >> 1;
|
||||||
}
|
}
|
||||||
temp = bc_copy_num(power);
|
temp = bc_copy_num(power);
|
||||||
|
@ -79,10 +79,10 @@ void bc_raise(bc_num num1, long exponent, bc_num *result, size_t scale)
|
||||||
/* Do the calculation. */
|
/* Do the calculation. */
|
||||||
while (exponent > 0) {
|
while (exponent > 0) {
|
||||||
pwrscale = 2 * pwrscale;
|
pwrscale = 2 * pwrscale;
|
||||||
bc_multiply(power, power, &power, pwrscale);
|
bc_multiply_ex(power, power, &power, pwrscale);
|
||||||
if ((exponent & 1) == 1) {
|
if ((exponent & 1) == 1) {
|
||||||
calcscale = pwrscale + calcscale;
|
calcscale = pwrscale + calcscale;
|
||||||
bc_multiply(temp, power, &temp, calcscale);
|
bc_multiply_ex(temp, power, &temp, calcscale);
|
||||||
}
|
}
|
||||||
exponent = exponent >> 1;
|
exponent = exponent >> 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,10 +72,10 @@ raise_mod_status bc_raisemod(bc_num base, bc_num expo, bc_num mod, bc_num *resul
|
||||||
while (!bc_is_zero(exponent)) {
|
while (!bc_is_zero(exponent)) {
|
||||||
(void) bc_divmod(exponent, BCG(_two_), &exponent, &parity, 0);
|
(void) bc_divmod(exponent, BCG(_two_), &exponent, &parity, 0);
|
||||||
if (!bc_is_zero(parity)) {
|
if (!bc_is_zero(parity)) {
|
||||||
bc_multiply(temp, power, &temp, scale);
|
bc_multiply_ex(temp, power, &temp, scale);
|
||||||
(void) bc_modulo(temp, modulus, &temp, scale);
|
(void) bc_modulo(temp, modulus, &temp, scale);
|
||||||
}
|
}
|
||||||
bc_multiply(power, power, &power, scale);
|
bc_multiply_ex(power, power, &power, scale);
|
||||||
(void) bc_modulo(power, modulus, &power, scale);
|
(void) bc_modulo(power, modulus, &power, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ static void _bc_rec_mul(bc_num u, size_t ulen, bc_num v, size_t vlen, bc_num *pr
|
||||||
the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)).
|
the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale)
|
bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale)
|
||||||
{
|
{
|
||||||
bc_num pval;
|
bc_num pval;
|
||||||
size_t len1, len2;
|
size_t len1, len2;
|
||||||
|
@ -276,6 +276,5 @@ void bc_multiply(bc_num n1, bc_num n2, bc_num *prod, size_t scale)
|
||||||
if (bc_is_zero(pval)) {
|
if (bc_is_zero(pval)) {
|
||||||
pval->n_sign = PLUS;
|
pval->n_sign = PLUS;
|
||||||
}
|
}
|
||||||
bc_free_num(prod);
|
return pval;
|
||||||
*prod = pval;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ bool bc_sqrt(bc_num *num, size_t scale)
|
||||||
bc_int2num(&guess, 10);
|
bc_int2num(&guess, 10);
|
||||||
|
|
||||||
bc_int2num(&guess1, (*num)->n_len);
|
bc_int2num(&guess1, (*num)->n_len);
|
||||||
bc_multiply(guess1, point5, &guess1, 0);
|
bc_multiply_ex(guess1, point5, &guess1, 0);
|
||||||
guess1->n_scale = 0;
|
guess1->n_scale = 0;
|
||||||
bc_raise_bc_exponent(guess, guess1, &guess, 0);
|
bc_raise_bc_exponent(guess, guess1, &guess, 0);
|
||||||
bc_free_num (&guess1);
|
bc_free_num (&guess1);
|
||||||
|
@ -93,7 +93,7 @@ bool bc_sqrt(bc_num *num, size_t scale)
|
||||||
guess1 = bc_copy_num(guess);
|
guess1 = bc_copy_num(guess);
|
||||||
bc_divide(*num, guess, &guess, cscale);
|
bc_divide(*num, guess, &guess, cscale);
|
||||||
bc_add_ex(guess, guess1, &guess, 0);
|
bc_add_ex(guess, guess1, &guess, 0);
|
||||||
bc_multiply(guess, point5, &guess, cscale);
|
bc_multiply_ex(guess, point5, &guess, cscale);
|
||||||
bc_sub_ex(guess, guess1, &diff, cscale + 1);
|
bc_sub_ex(guess, guess1, &diff, cscale + 1);
|
||||||
if (bc_is_near_zero(diff, cscale)) {
|
if (bc_is_near_zero(diff, cscale)) {
|
||||||
if (cscale < rscale + 1) {
|
if (cscale < rscale + 1) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue