Skip to content

Commit 32547f1

Browse files
ext/bcmath: If the result is 0, n_scale is set to 0. (#18056)
1 parent fa1effd commit 32547f1

File tree

7 files changed

+25
-14
lines changed

7 files changed

+25
-14
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ PHP NEWS
44

55
- BCMath:
66
. Simplify `bc_divide()` code. (SakiTakamachi)
7+
. If the result is 0, n_scale is set to 0. (SakiTakamachi)
78

89
- CLI:
910
. Add --ini=diff to print INI settings changed from the builtin default.

ext/bcmath/bcmath.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -807,8 +807,8 @@ PHP_FUNCTION(bcround)
807807
goto cleanup;
808808
}
809809

810-
bc_round(num, precision, mode, &result);
811-
RETVAL_NEW_STR(bc_num2str_ex(result, result->n_scale));
810+
size_t scale = bc_round(num, precision, mode, &result);
811+
RETVAL_NEW_STR(bc_num2str_ex(result, scale));
812812

813813
cleanup: {
814814
bc_free_num(&num);
@@ -1799,9 +1799,10 @@ PHP_METHOD(BcMath_Number, round)
17991799
bcmath_number_obj_t *intern = get_bcmath_number_from_zval(ZEND_THIS);
18001800

18011801
bc_num ret = NULL;
1802-
bc_round(intern->num, precision, rounding_mode, &ret);
1802+
size_t scale = bc_round(intern->num, precision, rounding_mode, &ret);
1803+
bc_rm_trailing_zeros(ret);
18031804

1804-
bcmath_number_obj_t *new_intern = bcmath_number_new_obj(ret, ret->n_scale);
1805+
bcmath_number_obj_t *new_intern = bcmath_number_new_obj(ret, scale);
18051806
RETURN_OBJ(&new_intern->std);
18061807
}
18071808

ext/bcmath/libbcmath/src/bcmath.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quo, bc_num *rem, size_t scale)
157157

158158
bc_num bc_floor_or_ceil(bc_num num, bool is_floor);
159159

160-
void bc_round(bc_num num, zend_long places, zend_long mode, bc_num *result);
160+
size_t bc_round(bc_num num, zend_long places, zend_long mode, bc_num *result);
161161

162162
typedef enum {
163163
OK,

ext/bcmath/libbcmath/src/div.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
430430
_bc_rm_leading_zeros(*quot);
431431
if (bc_is_zero(*quot)) {
432432
(*quot)->n_sign = PLUS;
433+
(*quot)->n_scale = 0;
433434
} else {
434435
(*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
435436
}

ext/bcmath/libbcmath/src/divmod.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, size_t scale
7474
(*rem)->n_scale = MIN(scale, (*rem)->n_scale);
7575
if (bc_is_zero(*rem)) {
7676
(*rem)->n_sign = PLUS;
77+
(*rem)->n_scale = 0;
7778
}
7879

7980
return true;

ext/bcmath/libbcmath/src/recmul.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale)
264264
_bc_rm_leading_zeros(prod);
265265
if (bc_is_zero(prod)) {
266266
prod->n_sign = PLUS;
267+
prod->n_scale = 0;
267268
}
268269
return prod;
269270
}

ext/bcmath/libbcmath/src/round.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
#include "private.h"
1919
#include <stddef.h>
2020

21-
void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
21+
/* Returns the scale of the value after rounding. */
22+
size_t bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
2223
{
2324
/* clear result */
2425
bc_free_num(result);
@@ -43,19 +44,19 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
4344
case PHP_ROUND_HALF_ODD:
4445
case PHP_ROUND_TOWARD_ZERO:
4546
*result = bc_copy_num(BCG(_zero_));
46-
return;
47+
return 0;
4748

4849
case PHP_ROUND_CEILING:
4950
if (num->n_sign == MINUS) {
5051
*result = bc_copy_num(BCG(_zero_));
51-
return;
52+
return 0;
5253
}
5354
break;
5455

5556
case PHP_ROUND_FLOOR:
5657
if (num->n_sign == PLUS) {
5758
*result = bc_copy_num(BCG(_zero_));
58-
return;
59+
return 0;
5960
}
6061
break;
6162

@@ -67,7 +68,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
6768

6869
if (bc_is_zero(num)) {
6970
*result = bc_copy_num(BCG(_zero_));
70-
return;
71+
return 0;
7172
}
7273

7374
/* If precision is -3, it becomes 1000. */
@@ -78,7 +79,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
7879
}
7980
(*result)->n_value[0] = 1;
8081
(*result)->n_sign = num->n_sign;
81-
return;
82+
return 0;
8283
}
8384

8485
/* Just like bcadd('1', '1', 4) becomes '2.0000', it pads with zeros at the end if necessary. */
@@ -90,7 +91,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
9091
(*result)->n_sign = num->n_sign;
9192
memcpy((*result)->n_value, num->n_value, num->n_len + num->n_scale);
9293
}
93-
return;
94+
return precision;
9495
}
9596

9697
/*
@@ -222,7 +223,12 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
222223
}
223224

224225
check_zero:
225-
if (bc_is_zero(*result)) {
226-
(*result)->n_sign = PLUS;
226+
{
227+
size_t scale = (*result)->n_scale;
228+
if (bc_is_zero(*result)) {
229+
(*result)->n_sign = PLUS;
230+
(*result)->n_scale = 0;
231+
}
232+
return scale;
227233
}
228234
}

0 commit comments

Comments
 (0)