Skip to content

Commit d1e82b3

Browse files
committed
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.
1 parent 65b5751 commit d1e82b3

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

ext/bcmath/libbcmath/src/raisemod.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@
3838
#include "bcmath.h"
3939
#include "private.h"
4040

41+
42+
/* Truncate a number to zero scale. To avoid sharing issues (refcount and
43+
shared n_value) the number is copied, this copy is truncated, and the
44+
original number is "freed". */
45+
46+
static void
47+
_bc_truncate (bc_num *num)
48+
{
49+
bc_num temp;
50+
51+
temp = bc_new_num ((*num)->n_len, 0);
52+
temp->n_sign = (*num)->n_sign;
53+
memcpy (temp->n_value, (*num)->n_value, (*num)->n_len);
54+
bc_free_num (num);
55+
*num = temp;
56+
}
57+
58+
4159
/* Raise BASE to the EXPO power, reduced modulo MOD. The result is
4260
placed in RESULT. If a EXPO is not an integer,
4361
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)
6381
if (power->n_scale != 0)
6482
{
6583
bc_rt_warn ("non-zero scale in base");
66-
bc_divide (power, BCG(_one_), &power, 0); /*truncate */
84+
_bc_truncate (&power);
6785
}
6886

6987
/* Check the exponent for scale digits. */
7088
if (exponent->n_scale != 0)
7189
{
7290
bc_rt_warn ("non-zero scale in exponent");
73-
bc_divide (exponent, BCG(_one_), &exponent, 0); /*truncate */
91+
_bc_truncate (&exponent);
7492
}
7593

7694
/* Check the modulus for scale digits. */
7795
if (modulus->n_scale != 0)
7896
{
7997
bc_rt_warn ("non-zero scale in modulus");
80-
bc_divide (modulus, BCG(_one_), &modulus, 0); /*truncate */
98+
_bc_truncate (&modulus);
8199
}
82100

83101
/* Do the calculation. */

0 commit comments

Comments
 (0)