Skip to content

BCmath extension code reformatting #11896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions ext/bcmath/libbcmath/src/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,30 @@
N1 is added to N2 and the result placed into RESULT. SCALE_MIN
is the minimum scale for the result. */

void bc_add (bc_num n1, bc_num n2, bc_num *result, size_t scale_min)
void bc_add(bc_num n1, bc_num n2, bc_num *result, size_t scale_min)
{
bc_num sum = NULL;
int cmp_res;
size_t res_scale;

if (n1->n_sign == n2->n_sign) {
sum = _bc_do_add (n1, n2, scale_min);
sum = _bc_do_add(n1, n2, scale_min);
sum->n_sign = n1->n_sign;
} else {
/* subtraction must be done. */
/* Compare magnitudes. */
cmp_res = _bc_do_compare(n1, n2, false, false);
switch (cmp_res) {
switch (_bc_do_compare(n1, n2, false, false)) {
case -1:
/* n1 is less than n2, subtract n1 from n2. */
sum = _bc_do_sub (n2, n1, scale_min);
sum = _bc_do_sub(n2, n1, scale_min);
sum->n_sign = n2->n_sign;
break;
case 0:
case 0:
/* They are equal! return zero with the correct scale! */
res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale));
sum = bc_new_num (1, res_scale);
memset (sum->n_value, 0, res_scale+1);
sum = bc_new_num (1, MAX(scale_min, MAX(n1->n_scale, n2->n_scale)));
memset(sum->n_value, 0, sum->n_scale + 1);
break;
case 1:
case 1:
/* n2 is less than n1, subtract n2 from n1. */
sum = _bc_do_sub (n1, n2, scale_min);
sum = _bc_do_sub(n1, n2, scale_min);
sum->n_sign = n1->n_sign;
}
}
Expand Down
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/bcmath.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef struct bc_struct {
#include "../../php_bcmath.h" /* Needed for BCG() macro */

/* The base used in storing the numbers in n_value above.
Currently this MUST be 10. */
Currently, this MUST be 10. */

#define BASE 10

Expand Down
12 changes: 7 additions & 5 deletions ext/bcmath/libbcmath/src/compare.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
*************************************************************************/

#include <stdbool.h>
#include <stddef.h>
#include "bcmath.h"
#include "private.h"
#include <stddef.h>


/* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less
Expand All @@ -46,9 +46,11 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign, bool ignore_last)
/* First, compare signs. */
if (use_sign && n1->n_sign != n2->n_sign) {
if (n1->n_sign == PLUS) {
return (1); /* Positive N1 > Negative N2 */
/* Positive N1 > Negative N2 */
return (1);
} else {
return (-1); /* Negative N1 < Positive N1 */
/* Negative N1 < Positive N1 */
return (-1);
}
}

Expand Down Expand Up @@ -107,7 +109,7 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign, bool ignore_last)
/* They are equal up to the last part of the equal part of the fraction. */
if (n1->n_scale != n2->n_scale) {
if (n1->n_scale > n2->n_scale) {
for (count = n1->n_scale-n2->n_scale; count>0; count--) {
for (count = n1->n_scale - n2->n_scale; count > 0; count--) {
if (*n1ptr++ != 0) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
Expand All @@ -118,7 +120,7 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign, bool ignore_last)
}
}
} else {
for (count = n2->n_scale-n1->n_scale; count>0; count--) {
for (count = n2->n_scale - n1->n_scale; count > 0; count--) {
if (*n2ptr++ != 0) {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
Expand Down
10 changes: 5 additions & 5 deletions ext/bcmath/libbcmath/src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

/* pn prints the number NUM in base 10. */

static void out_char (char c)
static void out_char(char c)
{
putchar(c);
}
Expand All @@ -45,16 +45,16 @@ static void out_char (char c)
void pn(bc_num num)
{
bc_out_num(num, 10, out_char, 0);
out_char ('\n');
out_char('\n');
}


/* pv prints a character array as if it was a string of bcd digits. */
void pv (char *name, unsigned char *num, size_t len)
void pv(char *name, unsigned char *num, size_t len)
{
printf("%s=", name);
for (size_t i = 0; i < len; i++){
printf ("%c",BCD_CHAR(num[i]));
for (size_t i = 0; i < len; i++) {
printf("%c", BCD_CHAR(num[i]));
}
printf("\n");
}
105 changes: 49 additions & 56 deletions ext/bcmath/libbcmath/src/div.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "private.h"
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "zend_alloc.h"


Expand All @@ -43,7 +44,7 @@

static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char *result)
{
int carry, value;
size_t carry, value;
unsigned char *nptr, *rptr;

if (digit == 0) {
Expand All @@ -53,8 +54,8 @@ static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char
memcpy(result, num, size);
} else {
/* Initialize */
nptr = (unsigned char *) (num+size-1);
rptr = (unsigned char *) (result+size-1);
nptr = (unsigned char *) (num + size - 1);
rptr = (unsigned char *) (result + size - 1);
carry = 0;

while (size-- > 0) {
Expand All @@ -74,121 +75,113 @@ static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char
/* The full division routine. This computes N1 / N2. It returns
true if the division is ok and the result is in QUOT. The number of
digits after the decimal point is SCALE. It returns false if division
by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
{
bc_num qval;
unsigned char *num1, *num2;
unsigned char *ptr1, *ptr2, *n2ptr, *qptr;
int scale1, val;
unsigned int len1, len2, scale2, qdigits, extra, count;
unsigned int qdig, qguess, borrow, carry;
int scale1, val;
unsigned int len1, len2, scale2, qdigits, extra, count;
unsigned int qdig, qguess, borrow, carry;
unsigned char *mval;
unsigned int norm;
bool zero;
unsigned int norm;

/* Test for divide by zero. */
if (bc_is_zero(n2)) {
return false;
}

/* Test for divide by 1. If it is we must truncate. */
if (n2->n_scale == 0) {
if (n2->n_len == 1 && *n2->n_value == 1) {
qval = bc_new_num (n1->n_len, scale);
qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS);
memset (&qval->n_value[n1->n_len],0,scale);
memcpy (qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale,scale));
bc_free_num (quot);
*quot = qval;
}
/* Test for divide by 1. If it is we must truncate. */
if (n2->n_scale == 0 && n2->n_len == 1 && *n2->n_value == 1) {
qval = bc_new_num (n1->n_len, scale);
qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS);
memset(&qval->n_value[n1->n_len], 0, scale);
memcpy(qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale, scale));
bc_free_num (quot);
*quot = qval;
}

/* Set up the divide. Move the decimal point on n1 by n2's scale.
Remember, zeros on the end of num2 are wasted effort for dividing. */
scale2 = n2->n_scale;
n2ptr = (unsigned char *) n2->n_value+n2->n_len+scale2-1;
while ((scale2 > 0) && (*n2ptr-- == 0)) {
n2ptr = (unsigned char *) n2->n_value + n2->n_len + scale2 - 1;
while ((scale2 > 0) && (*n2ptr == 0)) {
scale2--;
n2ptr--;
}

len1 = n1->n_len + scale2;
scale1 = n1->n_scale - scale2;
if (scale1 < scale) {
extra = scale - scale1;
} else {
extra = 0;
}
num1 = (unsigned char *) safe_emalloc (1, n1->n_len+n1->n_scale, extra+2);
memset (num1, 0, n1->n_len+n1->n_scale+extra+2);
memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale);
extra = MAX(scale - scale1, 0);

num1 = (unsigned char *) safe_emalloc(1, n1->n_len + n1->n_scale, extra + 2);
memset(num1, 0, n1->n_len + n1->n_scale + extra + 2);
memcpy(num1 + 1, n1->n_value, n1->n_len + n1->n_scale);

len2 = n2->n_len + scale2;
num2 = (unsigned char *) safe_emalloc (1, len2, 1);
memcpy (num2, n2->n_value, len2);
*(num2+len2) = 0;
num2 = (unsigned char *) safe_emalloc(1, len2, 1);
memcpy(num2, n2->n_value, len2);
*(num2 + len2) = 0;
n2ptr = num2;
while (*n2ptr == 0) {
n2ptr++;
len2--;
}

/* Calculate the number of quotient digits. */
if (len2 > len1+scale) {
qdigits = scale+1;
if (len2 > len1 + scale) {
qdigits = scale + 1;
zero = true;
} else {
zero = false;
if (len2 > len1) {
/* One for the zero integer part. */
qdigits = scale+1;
qdigits = scale + 1;
} else {
qdigits = len1-len2+scale+1;
qdigits = len1 - len2 + scale + 1;
}
}

/* Allocate and zero the storage for the quotient. */
qval = bc_new_num (qdigits-scale,scale);
memset (qval->n_value, 0, qdigits);
qval = bc_new_num (qdigits - scale, scale);
memset(qval->n_value, 0, qdigits);

/* Allocate storage for the temporary storage mval. */
mval = (unsigned char *) safe_emalloc(1, len2, 1);

/* Now for the full divide algorithm. */
if (!zero) {
/* Normalize */
norm = 10 / ((int)*n2ptr + 1);
norm = 10 / ((int) *n2ptr + 1);
if (norm != 1) {
_one_mult (num1, len1+scale1+extra+1, norm, num1);
_one_mult (n2ptr, len2, norm, n2ptr);
_one_mult(num1, len1 + scale1 + extra + 1, norm, num1);
_one_mult(n2ptr, len2, norm, n2ptr);
}

/* Initialize divide loop. */
qdig = 0;
if (len2 > len1) {
qptr = (unsigned char *) qval->n_value+len2-len1;
qptr = (unsigned char *) qval->n_value + len2 - len1;
} else {
qptr = (unsigned char *) qval->n_value;
}

/* Loop */
while (qdig <= len1+scale-len2) {
while (qdig <= len1 + scale - len2) {
/* Calculate the quotient digit guess. */
if (*n2ptr == num1[qdig]) {
qguess = 9;
} else {
qguess = (num1[qdig]*10 + num1[qdig+1]) / *n2ptr;
qguess = (num1[qdig] * 10 + num1[qdig + 1]) / *n2ptr;
}

/* Test qguess. */
if (
n2ptr[1]*qguess > (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 + num1[qdig+2]
) {
if (n2ptr[1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - *n2ptr * qguess) * 10 + num1[qdig + 2]) {
qguess--;
/* And again. */
if (
n2ptr[1]*qguess > (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 + num1[qdig+2]
) {
if (n2ptr[1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - *n2ptr * qguess) * 10 + num1[qdig + 2]) {
qguess--;
}
}
Expand All @@ -197,10 +190,10 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
borrow = 0;
if (qguess != 0) {
*mval = 0;
_one_mult (n2ptr, len2, qguess, mval+1);
ptr1 = (unsigned char *) num1+qdig+len2;
ptr2 = (unsigned char *) mval+len2;
for (count = 0; count < len2+1; count++) {
_one_mult(n2ptr, len2, qguess, mval + 1);
ptr1 = (unsigned char *) num1 + qdig + len2;
ptr2 = (unsigned char *) mval + len2;
for (count = 0; count < len2 + 1; count++) {
val = (int) *ptr1 - (int) *ptr2-- - borrow;
if (val < 0) {
val += 10;
Expand All @@ -215,8 +208,8 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
/* Test for negative result. */
if (borrow == 1) {
qguess--;
ptr1 = (unsigned char *) num1+qdig+len2;
ptr2 = (unsigned char *) n2ptr+len2-1;
ptr1 = (unsigned char *) num1 + qdig + len2;
ptr2 = (unsigned char *) n2ptr + len2 - 1;
carry = 0;
for (count = 0; count < len2; count++) {
val = (int) *ptr1 + (int) *ptr2-- + carry;
Expand All @@ -240,7 +233,7 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
}

/* Clean up and return the number. */
qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS);
if (bc_is_zero(qval)) {
qval->n_sign = PLUS;
}
Expand Down
8 changes: 4 additions & 4 deletions ext/bcmath/libbcmath/src/divmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, size_t scale
}

/* Calculate final scale. */
rscale = MAX (num1->n_scale, num2->n_scale+scale);
rscale = MAX (num1->n_scale, num2->n_scale + scale);
bc_init_num(&temp);

/* Calculate it. */
bc_divide (num1, num2, &temp, 0);
bc_divide(num1, num2, &temp, 0);
if (quot) {
quotient = bc_copy_num(temp);
}
bc_multiply (temp, num2, &temp, rscale);
bc_sub (num1, temp, rem, rscale);
bc_multiply(temp, num2, &temp, rscale);
bc_sub(num1, temp, rem, rscale);
bc_free_num (&temp);

if (quot) {
Expand Down
Loading