Skip to content

ext/bcmath: Use an enum for comparison result #14374

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 1 commit into from
May 30, 2024
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
6 changes: 3 additions & 3 deletions ext/bcmath/libbcmath/src/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ bc_num bc_add(bc_num n1, bc_num n2, size_t scale_min)
/* subtraction must be done. */
/* Compare magnitudes. */
switch (_bc_do_compare(n1, n2, false)) {
case -1:
case BCMATH_RIGHT_GREATER:
/* n1 is less than n2, subtract n1 from n2. */
sum = _bc_do_sub(n2, n1);
sum->n_sign = n2->n_sign;
break;
case 0:
case BCMATH_EQUAL:
/* They are equal! return zero with the correct scale! */
sum = bc_new_num (1, MAX(scale_min, MAX(n1->n_scale, n2->n_scale)));
break;
case 1:
case BCMATH_LEFT_GREATER:
/* n2 is less than n1, subtract n2 from n1. */
sum = _bc_do_sub(n1, n2);
sum->n_sign = n1->n_sign;
Expand Down
8 changes: 7 additions & 1 deletion ext/bcmath/libbcmath/src/bcmath.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ void bc_int2num(bc_num *num, int val);

long bc_num2long(bc_num num);

int bc_compare(bc_num n1, bc_num n2);
typedef enum {
BCMATH_EQUAL = 0,
BCMATH_LEFT_GREATER = 1,
BCMATH_RIGHT_GREATER = -1
} bcmath_compare_result;

bcmath_compare_result bc_compare(bc_num n1, bc_num n2);

bool bc_is_zero(bc_num num);

Expand Down
34 changes: 17 additions & 17 deletions ext/bcmath/libbcmath/src/compare.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@
than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just
compare the magnitudes. */

int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
{
char *n1ptr, *n2ptr;

/* First, compare signs. */
if (use_sign && n1->n_sign != n2->n_sign) {
if (n1->n_sign == PLUS) {
/* Positive N1 > Negative N2 */
return (1);
return BCMATH_LEFT_GREATER;
} else {
/* Negative N1 < Positive N1 */
return (-1);
return BCMATH_RIGHT_GREATER;
}
}

Expand All @@ -59,16 +59,16 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
if (n1->n_len > n2->n_len) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
return (1);
return BCMATH_LEFT_GREATER;
} else {
return (-1);
return BCMATH_RIGHT_GREATER;
}
} else {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
return (-1);
return BCMATH_RIGHT_GREATER;
} else {
return (1);
return BCMATH_LEFT_GREATER;
}
}
}
Expand All @@ -89,16 +89,16 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
if (*n1ptr > *n2ptr) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
return (1);
return BCMATH_LEFT_GREATER;
} else {
return (-1);
return BCMATH_RIGHT_GREATER;
}
} else {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
return (-1);
return BCMATH_RIGHT_GREATER;
} else {
return (1);
return BCMATH_LEFT_GREATER;
}
}
}
Expand All @@ -110,9 +110,9 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
if (*n1ptr++ != 0) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
return (1);
return BCMATH_LEFT_GREATER;
} else {
return (-1);
return BCMATH_RIGHT_GREATER;
}
}
}
Expand All @@ -121,22 +121,22 @@ int _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
if (*n2ptr++ != 0) {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
return (-1);
return BCMATH_RIGHT_GREATER;
} else {
return (1);
return BCMATH_LEFT_GREATER;
}
}
}
}
}

/* They must be equal! */
return (0);
return BCMATH_EQUAL;
}


/* This is the "user callable" routine to compare numbers N1 and N2. */
int bc_compare(bc_num n1, bc_num n2)
bcmath_compare_result bc_compare(bc_num n1, bc_num n2)
{
return _bc_do_compare(n1, n2, true);
}
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static inline uint64_t BC_BSWAP64(uint64_t u)


/* routines */
int _bc_do_compare (bc_num n1, bc_num n2, bool use_sign);
bcmath_compare_result _bc_do_compare (bc_num n1, bc_num n2, bool use_sign);
bc_num _bc_do_add (bc_num n1, bc_num n2);
bc_num _bc_do_sub (bc_num n1, bc_num n2);
void _bc_rm_leading_zeros (bc_num num);
26 changes: 14 additions & 12 deletions ext/bcmath/libbcmath/src/raisemod.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ raise_mod_status bc_raisemod(bc_num base, bc_num expo, bc_num mod, bc_num *resul
return MOD_IS_ZERO;
}

/* Any integer number mod 1 (or -1) must be equal to 0 */
if (_bc_do_compare(mod, BCG(_one_), false) == BCMATH_EQUAL) {
bc_free_num (result);
*result = bc_new_num(1, scale);
return OK;
}

/* Set initial values. */
power = bc_copy_num(base);
exponent = bc_copy_num(expo);
Expand All @@ -66,19 +73,14 @@ raise_mod_status bc_raisemod(bc_num base, bc_num expo, bc_num mod, bc_num *resul
bc_init_num(&parity);

/* Do the calculation. */
if (!_bc_do_compare(modulus, BCG(_one_), false)) {
bc_free_num (&temp);
temp = bc_new_num (1, scale);
} else {
while (!bc_is_zero(exponent)) {
(void) bc_divmod(exponent, BCG(_two_), &exponent, &parity, 0);
if (!bc_is_zero(parity)) {
bc_multiply_ex(temp, power, &temp, scale);
(void) bc_modulo(temp, modulus, &temp, scale);
}
bc_multiply_ex(power, power, &power, scale);
(void) bc_modulo(power, modulus, &power, scale);
while (!bc_is_zero(exponent)) {
(void) bc_divmod(exponent, BCG(_two_), &exponent, &parity, 0);
if (!bc_is_zero(parity)) {
bc_multiply_ex(temp, power, &temp, scale);
(void) bc_modulo(temp, modulus, &temp, scale);
}
bc_multiply_ex(power, power, &power, scale);
(void) bc_modulo(power, modulus, &power, scale);
}

/* Assign the value. */
Expand Down
34 changes: 18 additions & 16 deletions ext/bcmath/libbcmath/src/sqrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,49 @@

bool bc_sqrt(bc_num *num, size_t scale)
{
const bc_num local_num = *num;
/* Initial checks. */
int cmp_res = bc_compare(*num, BCG(_zero_));
if (cmp_res < 0) {
return false; /* error */
} else {
if (cmp_res == 0) {
bc_free_num (num);
*num = bc_copy_num(BCG(_zero_));
return true;
}
if (bc_is_neg(local_num)) {
/* Cannot take the square root of a negative number */
return false;
}
/* Square root of 0 is 0 */
if (bc_is_zero(local_num)) {
bc_free_num (num);
*num = bc_copy_num(BCG(_zero_));
return true;
}
cmp_res = bc_compare(*num, BCG(_one_));
if (cmp_res == 0) {

bcmath_compare_result num_cmp_one = bc_compare(local_num, BCG(_one_));
/* Square root of 1 is 1 */
if (num_cmp_one == BCMATH_EQUAL) {
bc_free_num (num);
*num = bc_copy_num(BCG(_one_));
return true;
}

/* Initialize the variables. */
size_t rscale;
size_t cscale;
bc_num guess, guess1, point5, diff;
size_t rscale = MAX(scale, local_num->n_scale);

rscale = MAX (scale, (*num)->n_scale);
bc_init_num(&guess1);
bc_init_num(&diff);
point5 = bc_new_num (1, 1);
point5->n_value[1] = 5;


/* Calculate the initial guess. */
if (cmp_res < 0) {
if (num_cmp_one == BCMATH_RIGHT_GREATER) {
/* The number is between 0 and 1. Guess should start at 1. */
guess = bc_copy_num(BCG(_one_));
cscale = (*num)->n_scale;
cscale = local_num->n_scale;
} else {
/* The number is greater than 1. Guess should start at 10^(exp/2). */
bc_init_num(&guess);
bc_int2num(&guess, 10);

bc_int2num(&guess1, (*num)->n_len);
bc_int2num(&guess1, local_num->n_len);
bc_multiply_ex(guess1, point5, &guess1, 0);
guess1->n_scale = 0;
bc_raise_bc_exponent(guess, guess1, &guess, 0);
Expand Down
6 changes: 3 additions & 3 deletions ext/bcmath/libbcmath/src/sub.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ bc_num bc_sub(bc_num n1, bc_num n2, size_t scale_min)
/* subtraction must be done. */
/* Compare magnitudes. */
switch (_bc_do_compare(n1, n2, false)) {
case -1:
case BCMATH_RIGHT_GREATER:
/* n1 is less than n2, subtract n1 from n2. */
diff = _bc_do_sub(n2, n1);
diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS);
break;
case 0: {
case BCMATH_EQUAL: {
/* They are equal! return zero! */
size_t res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale));
diff = bc_new_num (1, res_scale);
break;
}
case 1:
case BCMATH_LEFT_GREATER:
/* n2 is less than n1, subtract n2 from n1. */
diff = _bc_do_sub(n1, n2);
diff->n_sign = n1->n_sign;
Expand Down
Loading