Skip to content

Commit 17f094d

Browse files
committed
wip
1 parent 5f12fff commit 17f094d

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

ext/bcmath/bcmath.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,7 @@ static inline void bcmath_number_add_internal(
10081008
*scale = MAX(n1_full_scale, n2_full_scale);
10091009
}
10101010
*ret = bc_add(n1, n2, *scale);
1011+
bc_rm_trailing_zeros(*ret);
10111012
}
10121013

10131014
static inline void bcmath_number_sub_internal(
@@ -1018,6 +1019,7 @@ static inline void bcmath_number_sub_internal(
10181019
*scale = MAX(n1_full_scale, n2_full_scale);
10191020
}
10201021
*ret = bc_sub(n1, n2, *scale);
1022+
bc_rm_trailing_zeros(*ret);
10211023
}
10221024

10231025
static inline void bcmath_number_mul_internal(
@@ -1028,6 +1030,7 @@ static inline void bcmath_number_mul_internal(
10281030
*scale = n1_full_scale + n2_full_scale;
10291031
}
10301032
*ret = bc_multiply(n1, n2, *scale);
1033+
bc_rm_trailing_zeros(*ret);
10311034
}
10321035

10331036
static inline zend_result bcmath_number_div_internal(
@@ -1041,6 +1044,12 @@ static inline zend_result bcmath_number_div_internal(
10411044
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
10421045
return FAILURE;
10431046
}
1047+
size_t ret_scale = (*ret)->n_scale;
1048+
bc_rm_trailing_zeros(*ret);
1049+
if (auto_scale) {
1050+
size_t diff = ret_scale - (*ret)->n_scale;
1051+
*scale -= diff > BC_MATH_NUMBER_MAX_EX_SCALE ? BC_MATH_NUMBER_MAX_EX_SCALE : diff;
1052+
}
10441053
return SUCCESS;
10451054
}
10461055

@@ -1055,6 +1064,7 @@ static inline zend_result bcmath_number_mod_internal(
10551064
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
10561065
return FAILURE;
10571066
}
1067+
bc_rm_trailing_zeros(*ret);
10581068
return SUCCESS;
10591069
}
10601070

@@ -1073,11 +1083,13 @@ static inline zend_result bcmath_number_pow_internal(
10731083
}
10741084
long exponent = bc_num2long(n2);
10751085

1086+
bool scale_expand = false;
10761087
if (auto_scale) {
10771088
if (exponent > 0) {
10781089
*scale = n1_full_scale * exponent;
10791090
} else if (exponent < 0) {
10801091
*scale = n1_full_scale + BC_MATH_NUMBER_MAX_EX_SCALE;
1092+
scale_expand = true;
10811093
} else {
10821094
*scale = 0;
10831095
}
@@ -1092,6 +1104,12 @@ static inline zend_result bcmath_number_pow_internal(
10921104
return FAILURE;
10931105
}
10941106
bc_raise(n1, exponent, ret, *scale);
1107+
size_t ret_scale = (*ret)->n_scale;
1108+
bc_rm_trailing_zeros(*ret);
1109+
if (scale_expand) {
1110+
size_t diff = ret_scale - (*ret)->n_scale;
1111+
*scale -= diff > BC_MATH_NUMBER_MAX_EX_SCALE ? BC_MATH_NUMBER_MAX_EX_SCALE : diff;
1112+
}
10951113
return SUCCESS;
10961114
}
10971115

@@ -1382,6 +1400,8 @@ PHP_METHOD(BcMath_Number, powmod)
13821400
bc_free_num(&modulus_num);
13831401
}
13841402

1403+
bc_rm_trailing_zeros(ret);
1404+
13851405
bcmath_number_obj_t *new_intern = bcmath_number_new_obj(ret, scale);
13861406
RETURN_OBJ(&new_intern->std);
13871407

@@ -1413,7 +1433,7 @@ PHP_METHOD(BcMath_Number, sqrt)
14131433

14141434
size_t scale;
14151435
if (scale_is_null) {
1416-
scale = intern->num->n_scale;
1436+
scale = intern->scale + BC_MATH_NUMBER_MAX_EX_SCALE;
14171437
} else {
14181438
scale = arg_scale;
14191439
}
@@ -1425,6 +1445,13 @@ PHP_METHOD(BcMath_Number, sqrt)
14251445
RETURN_THROWS();
14261446
}
14271447

1448+
size_t ret_scale = ret->n_scale;
1449+
bc_rm_trailing_zeros(ret);
1450+
if (scale_is_null) {
1451+
size_t diff = ret_scale - ret->n_scale;
1452+
scale -= diff > BC_MATH_NUMBER_MAX_EX_SCALE ? BC_MATH_NUMBER_MAX_EX_SCALE : diff;
1453+
}
1454+
14281455
bcmath_number_obj_t *new_intern = bcmath_number_new_obj(ret, scale);
14291456
RETURN_OBJ(&new_intern->std);
14301457
}
@@ -1522,6 +1549,8 @@ PHP_METHOD(BcMath_Number, round)
15221549
bc_num ret = NULL;
15231550
bc_round(intern->num, precision, rounding_mode, &ret);
15241551

1552+
bc_rm_trailing_zeros(ret);
1553+
15251554
bcmath_number_obj_t *new_intern = bcmath_number_new_obj(ret, ret->n_scale);
15261555
RETURN_OBJ(&new_intern->std);
15271556
}

ext/bcmath/libbcmath/src/bcmath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ bool bc_is_near_zero(bc_num num, size_t scale);
124124

125125
bool bc_is_neg(bc_num num);
126126

127+
void bc_rm_trailing_zeros(bc_num num);
128+
127129
bc_num bc_add(bc_num n1, bc_num n2, size_t scale_min);
128130

129131
#define bc_add_ex(n1, n2, result, scale_min) do { \

ext/bcmath/libbcmath/src/rmzero.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,16 @@ void _bc_rm_leading_zeros(bc_num num)
4444
num->n_len--;
4545
}
4646
}
47+
48+
void bc_rm_trailing_zeros(bc_num num)
49+
{
50+
if (num->n_scale == 0) {
51+
return;
52+
}
53+
54+
char *end = num->n_value + num->n_len + num->n_scale - 1;
55+
while (*end == 0 && num->n_scale > 0) {
56+
num->n_scale--;
57+
end--;
58+
}
59+
}

0 commit comments

Comments
 (0)