diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2017-09-09 18:41:59 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2017-09-09 18:41:59 +0200 |
commit | d1e82b39e2c87961565da9f5b869829dd0da0437 (patch) | |
tree | d482988fd34bbddf20b628a3746aac8957b0e40b /ext/bcmath/libbcmath | |
parent | 65b575134fe286b2ce8b23181eb70f0ecda5ac16 (diff) | |
download | php-git-d1e82b39e2c87961565da9f5b869829dd0da0437.tar.gz |
Optimize truncation to zero scale in bc_raisemod()
There's no need to use a division by one to truncate to zero scale;
instead we introduce and use `_bc_truncate()`, what is more efficient.
Diffstat (limited to 'ext/bcmath/libbcmath')
-rw-r--r-- | ext/bcmath/libbcmath/src/raisemod.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 84788b4770..821dddb870 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -38,6 +38,24 @@ #include "bcmath.h" #include "private.h" + +/* Truncate a number to zero scale. To avoid sharing issues (refcount and + shared n_value) the number is copied, this copy is truncated, and the + original number is "freed". */ + +static void +_bc_truncate (bc_num *num) +{ + bc_num temp; + + temp = bc_new_num ((*num)->n_len, 0); + temp->n_sign = (*num)->n_sign; + memcpy (temp->n_value, (*num)->n_value, (*num)->n_len); + bc_free_num (num); + *num = temp; +} + + /* Raise BASE to the EXPO power, reduced modulo MOD. The result is placed in RESULT. If a EXPO is not an integer, only the integer part is used. */ @@ -63,21 +81,21 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) if (power->n_scale != 0) { bc_rt_warn ("non-zero scale in base"); - bc_divide (power, BCG(_one_), &power, 0); /*truncate */ + _bc_truncate (&power); } /* Check the exponent for scale digits. */ if (exponent->n_scale != 0) { bc_rt_warn ("non-zero scale in exponent"); - bc_divide (exponent, BCG(_one_), &exponent, 0); /*truncate */ + _bc_truncate (&exponent); } /* Check the modulus for scale digits. */ if (modulus->n_scale != 0) { bc_rt_warn ("non-zero scale in modulus"); - bc_divide (modulus, BCG(_one_), &modulus, 0); /*truncate */ + _bc_truncate (&modulus); } /* Do the calculation. */ |