summaryrefslogtreecommitdiff
path: root/ext/bcmath/libbcmath
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2017-09-09 18:41:59 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2017-09-09 18:41:59 +0200
commitd1e82b39e2c87961565da9f5b869829dd0da0437 (patch)
treed482988fd34bbddf20b628a3746aac8957b0e40b /ext/bcmath/libbcmath
parent65b575134fe286b2ce8b23181eb70f0ecda5ac16 (diff)
downloadphp-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.c24
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. */