Skip to content

Commit 4c5c237

Browse files
committed
WIP
1 parent 9c84d24 commit 4c5c237

File tree

11 files changed

+1209
-36
lines changed

11 files changed

+1209
-36
lines changed

ext/bcmath/bcmath.c

Lines changed: 921 additions & 6 deletions
Large diffs are not rendered by default.

ext/bcmath/bcmath.stub.php

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,83 @@
22

33
/** @generate-class-entries */
44

5-
/** @refcount 1 */
6-
function bcadd(string $num1, string $num2, ?int $scale = null): string {}
5+
namespace
6+
{
7+
/** @refcount 1 */
8+
function bcadd(string $num1, string $num2, ?int $scale = null): string {}
79

8-
/** @refcount 1 */
9-
function bcsub(string $num1, string $num2, ?int $scale = null): string {}
10+
/** @refcount 1 */
11+
function bcsub(string $num1, string $num2, ?int $scale = null): string {}
1012

11-
/** @refcount 1 */
12-
function bcmul(string $num1, string $num2, ?int $scale = null): string {}
13+
/** @refcount 1 */
14+
function bcmul(string $num1, string $num2, ?int $scale = null): string {}
1315

14-
/** @refcount 1 */
15-
function bcdiv(string $num1, string $num2, ?int $scale = null): string {}
16+
/** @refcount 1 */
17+
function bcdiv(string $num1, string $num2, ?int $scale = null): string {}
1618

17-
/** @refcount 1 */
18-
function bcmod(string $num1, string $num2, ?int $scale = null): string {}
19+
/** @refcount 1 */
20+
function bcmod(string $num1, string $num2, ?int $scale = null): string {}
1921

20-
/** @refcount 1 */
21-
function bcpowmod(string $num, string $exponent, string $modulus, ?int $scale = null): string {}
22+
/** @refcount 1 */
23+
function bcpowmod(string $num, string $exponent, string $modulus, ?int $scale = null): string {}
2224

23-
/** @refcount 1 */
24-
function bcpow(string $num, string $exponent, ?int $scale = null): string {}
25+
/** @refcount 1 */
26+
function bcpow(string $num, string $exponent, ?int $scale = null): string {}
2527

26-
/** @refcount 1 */
27-
function bcsqrt(string $num, ?int $scale = null): string {}
28+
/** @refcount 1 */
29+
function bcsqrt(string $num, ?int $scale = null): string {}
2830

29-
function bccomp(string $num1, string $num2, ?int $scale = null): int {}
31+
function bccomp(string $num1, string $num2, ?int $scale = null): int {}
3032

31-
function bcscale(?int $scale = null): int {}
33+
function bcscale(?int $scale = null): int {}
3234

33-
/** @refcount 1 */
34-
function bcfloor(string $num): string {}
35+
/** @refcount 1 */
36+
function bcfloor(string $num): string {}
3537

36-
/** @refcount 1 */
37-
function bcceil(string $num): string {}
38+
/** @refcount 1 */
39+
function bcceil(string $num): string {}
3840

39-
/** @refcount 1 */
40-
function bcround(string $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): string {}
41+
/** @refcount 1 */
42+
function bcround(string $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): string {}
43+
}
44+
45+
namespace BcMath
46+
{
47+
final readonly class Number implements \Stringable
48+
{
49+
public string $value;
50+
public int $scale;
51+
52+
public function __construct(string|int $num) {}
53+
54+
public function add(Number|string|int $num, ?int $scale = null): Number {}
55+
56+
public function sub(Number|string|int $num, ?int $scale = null): Number {}
57+
58+
public function mul(Number|string|int $num, ?int $scale = null): Number {}
59+
60+
public function div(Number|string|int $num, ?int $scale = null): Number {}
61+
62+
public function mod(Number|string|int $num, ?int $scale = null): Number {}
63+
64+
public function powmod(Number|string|int $exponent, Number|string|int $modulus, ?int $scale = null): Number {}
65+
66+
public function pow(Number|string|int $exponent, ?int $scale = null): Number {}
67+
68+
public function sqrt(?int $scale = null): Number {}
69+
70+
public function floor(): Number {}
71+
72+
public function ceil(): Number {}
73+
74+
public function round(int $precision = 0, int $mode = PHP_ROUND_HALF_UP): Number {}
75+
76+
public function compare(Number|string|int $num, ?int $scale = null): int {}
77+
78+
public function __toString(): string {}
79+
80+
public function __serialize(): array {}
81+
82+
public function __unserialize(array $data): void {}
83+
}
84+
}

ext/bcmath/bcmath_arginfo.h

Lines changed: 118 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/bcmath/config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ if test "$PHP_BCMATH" != "no"; then
1313
libbcmath/src/divmod.c
1414
libbcmath/src/doaddsub.c
1515
libbcmath/src/floor_or_ceil.c
16+
libbcmath/src/long2num.c
1617
libbcmath/src/init.c
1718
libbcmath/src/int2num.c
1819
libbcmath/src/nearzero.c

ext/bcmath/config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ARG_ENABLE("bcmath", "bc style precision math functions", "yes");
55
if (PHP_BCMATH == "yes") {
66
EXTENSION("bcmath", "bcmath.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
77
ADD_SOURCES("ext/bcmath/libbcmath/src", "add.c div.c init.c neg.c \
8-
raisemod.c sub.c compare.c divmod.c int2num.c \
8+
raisemod.c sub.c compare.c divmod.c int2num.c long2num.c \
99
num2long.c recmul.c sqrt.c zero.c doaddsub.c \
1010
floor_or_ceil.c nearzero.c num2str.c raise.c rmzero.c str2num.c \
1111
round.c convert.c", "bcmath");

ext/bcmath/libbcmath/src/bcmath.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ static inline bc_num bc_copy_num(bc_num num)
9898

9999
void bc_init_num(bc_num *num);
100100

101-
bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, bool auto_scale);
101+
bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, size_t *full_scale, bool auto_scale);
102+
103+
void bc_long2num(bc_num *num, zend_long lval);
102104

103105
zend_string *bc_num2str_ex(bc_num num, size_t scale);
104106

@@ -122,6 +124,8 @@ bool bc_is_near_zero(bc_num num, size_t scale);
122124

123125
bool bc_is_neg(bc_num num);
124126

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

127131
#define bc_add_ex(n1, n2, result, scale_min) do { \
@@ -146,7 +150,7 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale);
146150
*(result) = mul_ex; \
147151
} while (0)
148152

149-
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale);
153+
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, size_t scale);
150154

151155
bool bc_modulo(bc_num num1, bc_num num2, bc_num *resul, size_t scale);
152156

ext/bcmath/libbcmath/src/div.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static void _one_mult(unsigned char *num, size_t size, int digit, unsigned char
7676
true if the division is ok and the result is in QUOT. The number of
7777
digits after the decimal point is SCALE. It returns false if division
7878
by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
79-
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale)
79+
bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, size_t scale)
8080
{
8181
bc_num qval;
8282
unsigned char *num1, *num2;

ext/bcmath/libbcmath/src/long2num.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| [email protected] so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Authors: Saki Takamachi <[email protected]> |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#include "bcmath.h"
18+
#include <stdbool.h>
19+
20+
#if SIZEOF_ZEND_LONG == 8
21+
# define BC_LONG_MAX_DIGITS 19
22+
#else
23+
# define BC_LONG_MAX_DIGITS 10
24+
#endif
25+
26+
void bc_long2num(bc_num *num, zend_long lval)
27+
{
28+
if (UNEXPECTED(lval == 0)) {
29+
*num = bc_copy_num(BCG(_zero_));
30+
return;
31+
}
32+
33+
bool negative = lval < 0;
34+
if (UNEXPECTED(lval == LONG_MIN)) {
35+
*num = bc_new_num_nonzeroed(BC_LONG_MAX_DIGITS, 0);
36+
char *ptr = (*num)->n_value;
37+
memcpy(ptr, LONG_MIN_DIGITS, BC_LONG_MAX_DIGITS);
38+
for (size_t i = 0; i < BC_LONG_MAX_DIGITS; i++) {
39+
*ptr = *ptr - '0';
40+
ptr++;
41+
}
42+
(*num)->n_sign = MINUS;
43+
return;
44+
} else if (negative) {
45+
lval = -lval;
46+
}
47+
48+
zend_long tmp = lval;
49+
size_t len = 0;
50+
while (tmp > 0) {
51+
tmp /= BASE;
52+
len++;
53+
}
54+
55+
*num = bc_new_num_nonzeroed(len, 0);
56+
char *ptr = (*num)->n_value + len - 1;
57+
for (; len > 0; len--) {
58+
*ptr-- = lval % BASE;
59+
lval /= BASE;
60+
}
61+
(*num)->n_sign = negative ? MINUS : PLUS;
62+
}

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)