Skip to content

Commit

Permalink
Added scale to bc_compare argument (php#14802)
Browse files Browse the repository at this point in the history
In the original specification, the scale of bc_num was directly changed
and compared.

This becomes a problem when objects are supported, so we will modify it
to compare without changing bc_num.
  • Loading branch information
SakiTakamachi authored Jul 11, 2024
1 parent 32bf50a commit be4b10e
Show file tree
Hide file tree
Showing 8 changed files with 18 additions and 15 deletions.
2 changes: 1 addition & 1 deletion ext/bcmath/bcmath.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ PHP_FUNCTION(bccomp)
goto cleanup;
}

RETVAL_LONG(bc_compare(first, second));
RETVAL_LONG(bc_compare(first, second, scale));

cleanup: {
bc_free_num(&first);
Expand Down
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ bc_num bc_add(bc_num n1, bc_num n2, size_t scale_min)
} else {
/* subtraction must be done. */
/* Compare magnitudes. */
switch (_bc_do_compare(n1, n2, false)) {
switch (_bc_do_compare(n1, n2, scale_min, false)) {
case BCMATH_RIGHT_GREATER:
/* n1 is less than n2, subtract n1 from n2. */
sum = _bc_do_sub(n2, n1);
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 @@ -112,7 +112,7 @@ typedef enum {
BCMATH_RIGHT_GREATER = -1
} bcmath_compare_result;

bcmath_compare_result bc_compare(bc_num n1, bc_num n2);
bcmath_compare_result bc_compare(bc_num n1, bc_num n2, size_t scale);

bool bc_is_zero(bc_num num);

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

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

Expand Down Expand Up @@ -73,9 +73,12 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
}
}

size_t n1_scale = MIN(n1->n_scale, scale);
size_t n2_scale = MIN(n2->n_scale, scale);

/* If we get here, they have the same number of integer digits.
check the integer part and the equal length part of the fraction. */
size_t count = n1->n_len + MIN (n1->n_scale, n2->n_scale);
size_t count = n1->n_len + MIN (n1_scale, n2_scale);
n1ptr = n1->n_value;
n2ptr = n2->n_value;

Expand Down Expand Up @@ -104,9 +107,9 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
}

/* 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--) {
if (n1_scale != n2_scale) {
if (n1_scale > n2_scale) {
for (count = n1_scale - n2_scale; count > 0; count--) {
if (*n1ptr++ != 0) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
Expand All @@ -117,7 +120,7 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)
}
}
} else {
for (count = n2->n_scale - n1->n_scale; count > 0; count--) {
for (count = n2_scale - n1_scale; count > 0; count--) {
if (*n2ptr++ != 0) {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
Expand All @@ -136,7 +139,7 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, bool use_sign)


/* This is the "user callable" routine to compare numbers N1 and N2. */
bcmath_compare_result bc_compare(bc_num n1, bc_num n2)
bcmath_compare_result bc_compare(bc_num n1, bc_num n2, size_t scale)
{
return _bc_do_compare(n1, n2, true);
return _bc_do_compare(n1, n2, scale, 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 */
bcmath_compare_result _bc_do_compare (bc_num n1, bc_num n2, bool use_sign);
bcmath_compare_result _bc_do_compare (bc_num n1, bc_num n2, size_t scale, 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);
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/raisemod.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ raise_mod_status bc_raisemod(bc_num base, bc_num expo, bc_num mod, bc_num *resul
}

/* Any integer number mod 1 (or -1) must be equal to 0 */
if (_bc_do_compare(mod, BCG(_one_), false) == BCMATH_EQUAL) {
if (_bc_do_compare(mod, BCG(_one_), mod->n_scale, false) == BCMATH_EQUAL) {
bc_free_num (result);
*result = bc_new_num(1, scale);
return OK;
Expand Down
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/sqrt.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ bool bc_sqrt(bc_num *num, size_t scale)
return true;
}

bcmath_compare_result num_cmp_one = bc_compare(local_num, BCG(_one_));
bcmath_compare_result num_cmp_one = bc_compare(local_num, BCG(_one_), local_num->n_scale);
/* Square root of 1 is 1 */
if (num_cmp_one == BCMATH_EQUAL) {
bc_free_num (num);
Expand Down
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/sub.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ bc_num bc_sub(bc_num n1, bc_num n2, size_t scale_min)
} else {
/* subtraction must be done. */
/* Compare magnitudes. */
switch (_bc_do_compare(n1, n2, false)) {
switch (_bc_do_compare(n1, n2, scale_min, false)) {
case BCMATH_RIGHT_GREATER:
/* n1 is less than n2, subtract n1 from n2. */
diff = _bc_do_sub(n2, n1);
Expand Down

0 comments on commit be4b10e

Please sign in to comment.