ext/bcmath: use vector in compare (#18859)

This commit is contained in:
Saki Takamachi 2025-06-21 01:34:42 +09:00 committed by GitHub
parent feb1d63771
commit edfd55c197
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -39,6 +39,25 @@
than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just
compare the magnitudes. */
static inline bcmath_compare_result bc_compare_get_result_val(bool left_abs_greater, bool use_sign, sign left_sign)
{
if (left_abs_greater) {
/* Magnitude of left > right. */
if (!use_sign || left_sign == PLUS) {
return BCMATH_LEFT_GREATER;
} else {
return BCMATH_RIGHT_GREATER;
}
} else {
/* Magnitude of left < right. */
if (!use_sign || left_sign == PLUS) {
return BCMATH_RIGHT_GREATER;
} else {
return BCMATH_LEFT_GREATER;
}
}
}
bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, size_t scale, bool use_sign)
{
/* First, compare signs. */
@ -66,21 +85,7 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, size_t scale, bool us
/* Now compare the magnitude. */
if (n1->n_len != n2->n_len) {
if (n1->n_len > n2->n_len) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
return BCMATH_LEFT_GREATER;
} else {
return BCMATH_RIGHT_GREATER;
}
} else {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
return BCMATH_RIGHT_GREATER;
} else {
return BCMATH_LEFT_GREATER;
}
}
return bc_compare_get_result_val(n1->n_len > n2->n_len, use_sign, n1->n_sign);
}
size_t n1_scale = MIN(n1->n_scale, scale);
@ -92,6 +97,24 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, size_t scale, bool us
const char *n1ptr = n1->n_value;
const char *n2ptr = n2->n_value;
while (count >= sizeof(BC_VECTOR)) {
BC_VECTOR n1bytes;
BC_VECTOR n2bytes;
memcpy(&n1bytes, n1ptr, sizeof(BC_VECTOR));
memcpy(&n2bytes, n2ptr, sizeof(BC_VECTOR));
if (n1bytes != n2bytes) {
#if BC_LITTLE_ENDIAN
n1bytes = BC_BSWAP(n1bytes);
n2bytes = BC_BSWAP(n2bytes);
#endif
return bc_compare_get_result_val(n1bytes > n2bytes, use_sign, n1->n_sign);
}
count -= sizeof(BC_VECTOR);
n1ptr += sizeof(BC_VECTOR);
n2ptr += sizeof(BC_VECTOR);
}
while ((count > 0) && (*n1ptr == *n2ptr)) {
n1ptr++;
n2ptr++;
@ -99,21 +122,7 @@ bcmath_compare_result _bc_do_compare(bc_num n1, bc_num n2, size_t scale, bool us
}
if (count != 0) {
if (*n1ptr > *n2ptr) {
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS) {
return BCMATH_LEFT_GREATER;
} else {
return BCMATH_RIGHT_GREATER;
}
} else {
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS) {
return BCMATH_RIGHT_GREATER;
} else {
return BCMATH_LEFT_GREATER;
}
}
return bc_compare_get_result_val(*n1ptr > *n2ptr, use_sign, n1->n_sign);
}
/* They are equal up to the last part of the equal part of the fraction. */