Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
15644c1
Support object types in BCMath
SakiTakamachi Aug 27, 2024
72e9dce
Added operator tests
SakiTakamachi Aug 27, 2024
da683b6
Added basic tests
SakiTakamachi Aug 27, 2024
a8ed2d1
Fixed result scale and zero
SakiTakamachi Aug 28, 2024
2ac707f
Added method tests
SakiTakamachi Aug 28, 2024
14f12ac
Fixed test expected
SakiTakamachi Aug 28, 2024
33b80ee
revert force push
SakiTakamachi Aug 29, 2024
75d42ec
Fixed stub
SakiTakamachi Aug 29, 2024
56f5b82
Address comments
SakiTakamachi Aug 29, 2024
d149ca7
Fixed bcmath_number_get_properties_for
SakiTakamachi Aug 29, 2024
e4dc427
Added unset handler
SakiTakamachi Aug 29, 2024
4acfe22
Fixed and rename bcmath_number_isset_property
SakiTakamachi Aug 29, 2024
bb17daf
Added a comment about exponent
SakiTakamachi Aug 29, 2024
6c6d0d5
Added a comment about scale or rscale
SakiTakamachi Aug 29, 2024
c302167
Removed unnecessary bc_free_num()
SakiTakamachi Aug 29, 2024
a9b9c9f
use Z_PARAM_ARRAY_HT
SakiTakamachi Aug 29, 2024
62e6b3d
Increased constructor test cases and divided them into 32bit and 64bit
SakiTakamachi Aug 29, 2024
92856c4
Fixed bc_long2num
SakiTakamachi Aug 29, 2024
df6e0f1
Fixed cast and construct tests
SakiTakamachi Aug 29, 2024
ae04884
Fixed tests
SakiTakamachi Aug 29, 2024
0fbc177
Added BCMATH_PARSE_ / BCMATH_PARAM_ macros
SakiTakamachi Aug 29, 2024
48243ba
Fixed bc_long2num
SakiTakamachi Aug 29, 2024
c42e70f
Fixed test
SakiTakamachi Aug 29, 2024
3eedfe0
Added clone test
SakiTakamachi Aug 29, 2024
22b08ec
Added bc_free_num()
SakiTakamachi Aug 29, 2024
133a4ae
Fixed bc_long2num
SakiTakamachi Aug 29, 2024
5c38bf1
Fixed bc_free_num
SakiTakamachi Aug 29, 2024
b84d5e5
test
SakiTakamachi Aug 29, 2024
c81eca3
test
SakiTakamachi Aug 29, 2024
939ac83
test
SakiTakamachi Aug 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
987 changes: 981 additions & 6 deletions ext/bcmath/bcmath.c

Large diffs are not rendered by default.

95 changes: 71 additions & 24 deletions ext/bcmath/bcmath.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,86 @@

/** @generate-class-entries */

/** @refcount 1 */
function bcadd(string $num1, string $num2, ?int $scale = null): string {}
namespace
{
/** @refcount 1 */
function bcadd(string $num1, string $num2, ?int $scale = null): string {}

/** @refcount 1 */
function bcsub(string $num1, string $num2, ?int $scale = null): string {}
/** @refcount 1 */
function bcsub(string $num1, string $num2, ?int $scale = null): string {}

/** @refcount 1 */
function bcmul(string $num1, string $num2, ?int $scale = null): string {}
/** @refcount 1 */
function bcmul(string $num1, string $num2, ?int $scale = null): string {}

/** @refcount 1 */
function bcdiv(string $num1, string $num2, ?int $scale = null): string {}
/** @refcount 1 */
function bcdiv(string $num1, string $num2, ?int $scale = null): string {}

/** @refcount 1 */
function bcmod(string $num1, string $num2, ?int $scale = null): string {}
/** @refcount 1 */
function bcmod(string $num1, string $num2, ?int $scale = null): string {}

/** @refcount 1 */
function bcpowmod(string $num, string $exponent, string $modulus, ?int $scale = null): string {}
/** @refcount 1 */
function bcpowmod(string $num, string $exponent, string $modulus, ?int $scale = null): string {}

/** @refcount 1 */
function bcpow(string $num, string $exponent, ?int $scale = null): string {}
/** @refcount 1 */
function bcpow(string $num, string $exponent, ?int $scale = null): string {}

/** @refcount 1 */
function bcsqrt(string $num, ?int $scale = null): string {}
/** @refcount 1 */
function bcsqrt(string $num, ?int $scale = null): string {}

function bccomp(string $num1, string $num2, ?int $scale = null): int {}
function bccomp(string $num1, string $num2, ?int $scale = null): int {}

function bcscale(?int $scale = null): int {}
function bcscale(?int $scale = null): int {}

/** @refcount 1 */
function bcfloor(string $num): string {}
/** @refcount 1 */
function bcfloor(string $num): string {}

/** @refcount 1 */
function bcceil(string $num): string {}
/** @refcount 1 */
function bcceil(string $num): string {}

/** @refcount 1 */
function bcround(string $num, int $precision = 0, RoundingMode $mode = RoundingMode::HalfAwayFromZero): string {}
/** @refcount 1 */
function bcround(string $num, int $precision = 0, RoundingMode $mode = RoundingMode::HalfAwayFromZero): string {}
}

namespace BcMath
{
/** @strict-properties */
final readonly class Number implements \Stringable
{
/** @virtual */
public string $value;
/** @virtual */
public int $scale;

public function __construct(string|int $num) {}

public function add(Number|string|int $num, ?int $scale = null): Number {}

public function sub(Number|string|int $num, ?int $scale = null): Number {}

public function mul(Number|string|int $num, ?int $scale = null): Number {}

public function div(Number|string|int $num, ?int $scale = null): Number {}

public function mod(Number|string|int $num, ?int $scale = null): Number {}

public function powmod(Number|string|int $exponent, Number|string|int $modulus, ?int $scale = null): Number {}

public function pow(Number|string|int $exponent, ?int $scale = null): Number {}

public function sqrt(?int $scale = null): Number {}

public function floor(): Number {}

public function ceil(): Number {}

public function round(int $precision = 0, \RoundingMode $mode = \RoundingMode::HalfAwayFromZero): Number {}

public function compare(Number|string|int $num, ?int $scale = null): int {}

public function __toString(): string {}

public function __serialize(): array {}

public function __unserialize(array $data): void {}
}
}
118 changes: 117 additions & 1 deletion ext/bcmath/bcmath_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ext/bcmath/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ if test "$PHP_BCMATH" != "no"; then
libbcmath/src/divmod.c
libbcmath/src/doaddsub.c
libbcmath/src/floor_or_ceil.c
libbcmath/src/long2num.c
libbcmath/src/init.c
libbcmath/src/int2num.c
libbcmath/src/nearzero.c
Expand Down
2 changes: 1 addition & 1 deletion ext/bcmath/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ARG_ENABLE("bcmath", "bc style precision math functions", "yes");
if (PHP_BCMATH == "yes") {
EXTENSION("bcmath", "bcmath.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
ADD_SOURCES("ext/bcmath/libbcmath/src", "add.c div.c init.c neg.c \
raisemod.c sub.c compare.c divmod.c int2num.c \
raisemod.c sub.c compare.c divmod.c int2num.c long2num.c \
num2long.c recmul.c sqrt.c zero.c doaddsub.c \
floor_or_ceil.c nearzero.c num2str.c raise.c rmzero.c str2num.c \
round.c convert.c", "bcmath");
Expand Down
6 changes: 5 additions & 1 deletion ext/bcmath/libbcmath/src/bcmath.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ static inline bc_num bc_copy_num(bc_num num)

void bc_init_num(bc_num *num);

bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, bool auto_scale);
bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, size_t *full_scale, bool auto_scale);

bc_num bc_long2num(zend_long lval);

zend_string *bc_num2str_ex(bc_num num, size_t scale);

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

bool bc_is_neg(bc_num num);

void bc_rm_trailing_zeros(bc_num num);

bc_num bc_add(bc_num n1, bc_num n2, size_t scale_min);

#define bc_add_ex(n1, n2, result, scale_min) do { \
Expand Down
6 changes: 6 additions & 0 deletions ext/bcmath/libbcmath/src/divmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ bool bc_divmod(bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, size_t scale
*quot = quotient;
}

/* The value of rscale changes during processing. Here we use the value of scale. It's not a typo. */
(*rem)->n_scale = MIN(scale, (*rem)->n_scale);
if (bc_is_zero(*rem)) {
(*rem)->n_sign = PLUS;
}

return true;
}

Expand Down
59 changes: 59 additions & 0 deletions ext/bcmath/libbcmath/src/long2num.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Saki Takamachi <saki@php.net> |
+----------------------------------------------------------------------+
*/

#include "bcmath.h"
#include <stdbool.h>
#include "convert.h"

#define BC_LONG_MAX_DIGITS (sizeof(LONG_MIN_DIGITS) - 1)

bc_num bc_long2num(zend_long lval)
{
bc_num num;

if (UNEXPECTED(lval == 0)) {
num = bc_copy_num(BCG(_one_));
return num;
}

bool negative = lval < 0;
if (UNEXPECTED(lval == LONG_MIN)) {
num = bc_new_num_nonzeroed(BC_LONG_MAX_DIGITS, 0);
const char *ptr = LONG_MIN_DIGITS;
bc_copy_and_toggle_bcd(num->n_value, ptr, ptr + BC_LONG_MAX_DIGITS);
num->n_sign = MINUS;
return num;
} else if (negative) {
lval = -lval;
}

zend_long tmp = lval;
size_t len = 0;
while (tmp > 0) {
tmp /= BASE;
len++;
}

num = bc_new_num_nonzeroed(len, 0);
char *ptr = num->n_value + len - 1;
for (; len > 0; len--) {
*ptr-- = lval % BASE;
lval /= BASE;
}
num->n_sign = negative ? MINUS : PLUS;

return num;
}
4 changes: 1 addition & 3 deletions ext/bcmath/libbcmath/src/raise.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ void bc_raise(bc_num num1, long exponent, bc_num *result, size_t scale)
} else {
bc_free_num (result);
*result = temp;
if ((*result)->n_scale > rscale) {
(*result)->n_scale = rscale;
}
(*result)->n_scale = MIN(scale, (*result)->n_scale);
}
bc_free_num (&power);
}
Expand Down
13 changes: 13 additions & 0 deletions ext/bcmath/libbcmath/src/rmzero.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,16 @@ void _bc_rm_leading_zeros(bc_num num)
num->n_len--;
}
}

void bc_rm_trailing_zeros(bc_num num)
{
if (num->n_scale == 0) {
return;
}

char *end = num->n_value + num->n_len + num->n_scale - 1;
while (*end == 0 && num->n_scale > 0) {
num->n_scale--;
end--;
}
}
Loading