mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
[RFC] ext/bcmath: Added bcdivmod
(#15740)
RFC: https://wiki.php.net/rfc/add_bcdivmod_to_bcmath Added bcdivmod() function and added divmod() method to BcMath\Number class.
This commit is contained in:
parent
2b90acb469
commit
f6db576c31
11 changed files with 681 additions and 1 deletions
1
NEWS
1
NEWS
|
@ -5,6 +5,7 @@ PHP NEWS
|
|||
- BcMath:
|
||||
. bcpow() performance improvement. (Jorg Sowa)
|
||||
. ext/bcmath: Check for scale overflow. (SakiTakamachi)
|
||||
. [RFC] ext/bcmath: Added bcdivmod. (SakiTakamachi)
|
||||
|
||||
- Debugging:
|
||||
. Fixed bug GH-15923 (GDB: Python Exception <class 'TypeError'>:
|
||||
|
|
|
@ -780,6 +780,8 @@ PHP 8.4 UPGRADE NOTES
|
|||
- BCMath:
|
||||
. Added bcfloor(), bcceil(), bcround().
|
||||
RFC: https://wiki.php.net/rfc/adding_bcround_bcfloor_bcceil_to_bcmath
|
||||
. Added bcdivmod().
|
||||
RFC: https://wiki.php.net/rfc/add_bcdivmod_to_bcmath
|
||||
|
||||
- DOM:
|
||||
. Added DOMNode::compareDocumentPosition().
|
||||
|
|
|
@ -24,6 +24,7 @@ static const func_info_t func_infos[] = {
|
|||
F1("bcmul", MAY_BE_STRING),
|
||||
F1("bcdiv", MAY_BE_STRING),
|
||||
F1("bcmod", MAY_BE_STRING),
|
||||
F1("bcdivmod", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
F1("bcpowmod", MAY_BE_STRING),
|
||||
F1("bcpow", MAY_BE_STRING),
|
||||
F1("bcsqrt", MAY_BE_STRING),
|
||||
|
|
|
@ -434,6 +434,61 @@ PHP_FUNCTION(bcmod)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_FUNCTION(bcdivmod)
|
||||
{
|
||||
zend_string *left, *right;
|
||||
zend_long scale_param;
|
||||
bool scale_param_is_null = 1;
|
||||
bc_num first = NULL, second = NULL, quot = NULL, rem = NULL;
|
||||
int scale = BCG(bc_precision);
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(2, 3)
|
||||
Z_PARAM_STR(left)
|
||||
Z_PARAM_STR(right)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG_OR_NULL(scale_param, scale_param_is_null)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (scale_param_is_null) {
|
||||
scale = BCG(bc_precision);
|
||||
} else if (bcmath_check_scale(scale_param, 3) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
} else {
|
||||
scale = (int) scale_param;
|
||||
}
|
||||
|
||||
BC_ARENA_SETUP;
|
||||
|
||||
if (php_str2num(&first, left) == FAILURE) {
|
||||
zend_argument_value_error(1, "is not well-formed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (php_str2num(&second, right) == FAILURE) {
|
||||
zend_argument_value_error(2, "is not well-formed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!bc_divmod(first, second, ", &rem, scale)) {
|
||||
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zval z_quot, z_rem;
|
||||
ZVAL_STR(&z_quot, bc_num2str_ex(quot, 0));
|
||||
ZVAL_STR(&z_rem, bc_num2str_ex(rem, scale));
|
||||
|
||||
RETVAL_ARR(zend_new_pair(&z_quot, &z_rem));
|
||||
|
||||
cleanup: {
|
||||
bc_free_num(&first);
|
||||
bc_free_num(&second);
|
||||
bc_free_num(");
|
||||
bc_free_num(&rem);
|
||||
BC_ARENA_TEARDOWN;
|
||||
};
|
||||
}
|
||||
|
||||
/* {{{ Returns the value of an arbitrary precision number raised to the power of another reduced by a modulus */
|
||||
PHP_FUNCTION(bcpowmod)
|
||||
{
|
||||
|
@ -1452,6 +1507,65 @@ PHP_METHOD(BcMath_Number, pow)
|
|||
bcmath_number_calc_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_POW);
|
||||
}
|
||||
|
||||
PHP_METHOD(BcMath_Number, divmod)
|
||||
{
|
||||
zend_object *num_obj = NULL;
|
||||
zend_string *num_str = NULL;
|
||||
zend_long num_lval = 0;
|
||||
zend_long scale_lval = 0;
|
||||
bool scale_is_null = true;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 2)
|
||||
BCMATH_PARAM_NUMBER_OR_STR_OR_LONG(num_obj, bcmath_number_ce, num_str, num_lval);
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG_OR_NULL(scale_lval, scale_is_null);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
bc_num num = NULL;
|
||||
size_t num_full_scale;
|
||||
if (bc_num_from_obj_or_str_or_long_with_err(&num, &num_full_scale, num_obj, num_str, num_lval, 1) == FAILURE) {
|
||||
goto fail;
|
||||
}
|
||||
if (bcmath_check_scale(scale_lval, 2) == FAILURE) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bc_num quot = NULL;
|
||||
bc_num rem = NULL;
|
||||
size_t scale = scale_lval;
|
||||
bcmath_number_obj_t *intern = get_bcmath_number_from_zval(ZEND_THIS);
|
||||
|
||||
if (scale_is_null) {
|
||||
scale = MAX(intern->scale, num_full_scale);
|
||||
}
|
||||
|
||||
if (!bc_divmod(intern->num, num, ", &rem, scale)) {
|
||||
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
|
||||
goto fail;
|
||||
}
|
||||
bc_rm_trailing_zeros(quot);
|
||||
bc_rm_trailing_zeros(rem);
|
||||
|
||||
if (num_obj == NULL) {
|
||||
bc_free_num(&num);
|
||||
}
|
||||
|
||||
bcmath_number_obj_t *quot_intern = bcmath_number_new_obj(quot, 0);
|
||||
bcmath_number_obj_t *rem_intern = bcmath_number_new_obj(rem, scale);
|
||||
|
||||
zval z_quot, z_rem;
|
||||
ZVAL_OBJ(&z_quot, "_intern->std);
|
||||
ZVAL_OBJ(&z_rem, &rem_intern->std);
|
||||
|
||||
RETURN_ARR(zend_new_pair(&z_quot, &z_rem));
|
||||
|
||||
fail:
|
||||
if (num_obj == NULL) {
|
||||
bc_free_num(&num);
|
||||
}
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
PHP_METHOD(BcMath_Number, powmod)
|
||||
{
|
||||
zend_object *exponent_obj = NULL;
|
||||
|
|
|
@ -19,6 +19,12 @@ namespace
|
|||
/** @refcount 1 */
|
||||
function bcmod(string $num1, string $num2, ?int $scale = null): string {}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @refcount 1
|
||||
*/
|
||||
function bcdivmod(string $num1, string $num2, ?int $scale = null): array {}
|
||||
|
||||
/** @refcount 1 */
|
||||
function bcpowmod(string $num, string $exponent, string $modulus, ?int $scale = null): string {}
|
||||
|
||||
|
@ -64,6 +70,9 @@ namespace BcMath
|
|||
|
||||
public function mod(Number|string|int $num, ?int $scale = null): Number {}
|
||||
|
||||
/** @return Number[] */
|
||||
public function divmod(Number|string|int $num, ?int $scale = null): array {}
|
||||
|
||||
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 {}
|
||||
|
|
17
ext/bcmath/bcmath_arginfo.h
generated
17
ext/bcmath/bcmath_arginfo.h
generated
|
@ -1,5 +1,5 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: f3101bbd25da90d97801d53ea673789d1ce4f6a1 */
|
||||
* Stub hash: 687d6fb392a9b0c1329152cc0f62341a73e427f4 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_bcadd, 0, 2, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, num1, IS_STRING, 0)
|
||||
|
@ -15,6 +15,12 @@ ZEND_END_ARG_INFO()
|
|||
|
||||
#define arginfo_bcmod arginfo_bcadd
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_bcdivmod, 0, 2, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, num1, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, num2, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, scale, IS_LONG, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_bcpowmod, 0, 3, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, num, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, exponent, IS_STRING, 0)
|
||||
|
@ -72,6 +78,11 @@ ZEND_END_ARG_INFO()
|
|||
|
||||
#define arginfo_class_BcMath_Number_mod arginfo_class_BcMath_Number_add
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_BcMath_Number_divmod, 0, 1, IS_ARRAY, 0)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, num, BcMath\\\116umber, MAY_BE_STRING|MAY_BE_LONG, NULL)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, scale, IS_LONG, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_BcMath_Number_powmod, 0, 2, BcMath\\\116umber, 0)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, exponent, BcMath\\\116umber, MAY_BE_STRING|MAY_BE_LONG, NULL)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, modulus, BcMath\\\116umber, MAY_BE_STRING|MAY_BE_LONG, NULL)
|
||||
|
@ -117,6 +128,7 @@ ZEND_FUNCTION(bcsub);
|
|||
ZEND_FUNCTION(bcmul);
|
||||
ZEND_FUNCTION(bcdiv);
|
||||
ZEND_FUNCTION(bcmod);
|
||||
ZEND_FUNCTION(bcdivmod);
|
||||
ZEND_FUNCTION(bcpowmod);
|
||||
ZEND_FUNCTION(bcpow);
|
||||
ZEND_FUNCTION(bcsqrt);
|
||||
|
@ -131,6 +143,7 @@ ZEND_METHOD(BcMath_Number, sub);
|
|||
ZEND_METHOD(BcMath_Number, mul);
|
||||
ZEND_METHOD(BcMath_Number, div);
|
||||
ZEND_METHOD(BcMath_Number, mod);
|
||||
ZEND_METHOD(BcMath_Number, divmod);
|
||||
ZEND_METHOD(BcMath_Number, powmod);
|
||||
ZEND_METHOD(BcMath_Number, pow);
|
||||
ZEND_METHOD(BcMath_Number, sqrt);
|
||||
|
@ -148,6 +161,7 @@ static const zend_function_entry ext_functions[] = {
|
|||
ZEND_FE(bcmul, arginfo_bcmul)
|
||||
ZEND_FE(bcdiv, arginfo_bcdiv)
|
||||
ZEND_FE(bcmod, arginfo_bcmod)
|
||||
ZEND_FE(bcdivmod, arginfo_bcdivmod)
|
||||
ZEND_FE(bcpowmod, arginfo_bcpowmod)
|
||||
ZEND_FE(bcpow, arginfo_bcpow)
|
||||
ZEND_FE(bcsqrt, arginfo_bcsqrt)
|
||||
|
@ -166,6 +180,7 @@ static const zend_function_entry class_BcMath_Number_methods[] = {
|
|||
ZEND_ME(BcMath_Number, mul, arginfo_class_BcMath_Number_mul, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(BcMath_Number, div, arginfo_class_BcMath_Number_div, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(BcMath_Number, mod, arginfo_class_BcMath_Number_mod, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(BcMath_Number, divmod, arginfo_class_BcMath_Number_divmod, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(BcMath_Number, powmod, arginfo_class_BcMath_Number_powmod, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(BcMath_Number, pow, arginfo_class_BcMath_Number_pow, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(BcMath_Number, sqrt, arginfo_class_BcMath_Number_sqrt, ZEND_ACC_PUBLIC)
|
||||
|
|
46
ext/bcmath/tests/bcdivmod.phpt
Normal file
46
ext/bcmath/tests/bcdivmod.phpt
Normal file
|
@ -0,0 +1,46 @@
|
|||
--TEST--
|
||||
bcdivmod() function
|
||||
--EXTENSIONS--
|
||||
bcmath
|
||||
--INI--
|
||||
bcmath.scale=0
|
||||
--FILE--
|
||||
<?php
|
||||
require(__DIR__ . "/run_bcmath_tests_function.inc");
|
||||
|
||||
$dividends = ["15", "-15", "1", "-9", "14.14", "-16.60", "0.15", "-0.01"];
|
||||
$divisors = array_merge($dividends, [
|
||||
"15151324141414.412312232141241",
|
||||
"-132132245132134.1515123765412",
|
||||
"141241241241241248267654747412",
|
||||
"-149143276547656984948124912",
|
||||
"0.1322135476547459213732911312",
|
||||
"-0.123912932193769965476541321",
|
||||
]);
|
||||
|
||||
$scales = [0, 10];
|
||||
foreach ($scales as $scale) {
|
||||
foreach ($dividends as $firstTerm) {
|
||||
foreach ($divisors as $secondTerm) {
|
||||
[$quot, $rem] = bcdivmod($firstTerm, $secondTerm, $scale);
|
||||
$div_ret = bcdiv($firstTerm, $secondTerm, 0);
|
||||
$mod_ret = bcmod($firstTerm, $secondTerm, $scale);
|
||||
|
||||
if (bccomp($quot, $div_ret) !== 0) {
|
||||
echo "Div result is incorrect.\n";
|
||||
var_dump($firstTerm, $secondTerm, $scale, $quot, $rem, $div_ret, $mod_ret);
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
if (bccomp($rem, $mod_ret) !== 0) {
|
||||
echo "Mod result is incorrect.\n";
|
||||
var_dump($firstTerm, $secondTerm, $scale, $quot, $rem, $div_ret, $mod_ret);
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo 'done!';
|
||||
?>
|
||||
--EXPECT--
|
||||
done!
|
66
ext/bcmath/tests/bcdivmod_by_zero.phpt
Normal file
66
ext/bcmath/tests/bcdivmod_by_zero.phpt
Normal file
|
@ -0,0 +1,66 @@
|
|||
--TEST--
|
||||
bcdivmod() function div by zero
|
||||
--EXTENSIONS--
|
||||
bcmath
|
||||
--INI--
|
||||
bcmath.scale=0
|
||||
--FILE--
|
||||
<?php
|
||||
require(__DIR__ . "/run_bcmath_tests_function.inc");
|
||||
|
||||
$dividends = [
|
||||
"15", "-15", "1", "-9", "14.14", "-16.60", "0.15", "-0.01",
|
||||
"15151324141414.412312232141241",
|
||||
"-132132245132134.1515123765412",
|
||||
"141241241241241248267654747412",
|
||||
"-149143276547656984948124912",
|
||||
"0.1322135476547459213732911312",
|
||||
"-0.123912932193769965476541321",
|
||||
];
|
||||
|
||||
$divisors = [
|
||||
'0',
|
||||
'0.00',
|
||||
];
|
||||
|
||||
foreach ($dividends as $firstTerm) {
|
||||
foreach ($divisors as $secondTerm) {
|
||||
try {
|
||||
bcdivmod($firstTerm, $secondTerm);
|
||||
echo "NG\n";
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage() === 'Division by zero' ? 'OK' :'NG';
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
||||
OK
|
157
ext/bcmath/tests/number/methods/div_mod_by_zero.phpt
Normal file
157
ext/bcmath/tests/number/methods/div_mod_by_zero.phpt
Normal file
|
@ -0,0 +1,157 @@
|
|||
--TEST--
|
||||
BcMath\Number div(), mod(), divmod() by zero
|
||||
--EXTENSIONS--
|
||||
bcmath
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$values1 = ['100', '-100'];
|
||||
|
||||
$values2 = [
|
||||
[0, 'int'],
|
||||
[-0, 'int'],
|
||||
['0', 'string'],
|
||||
['-0', 'string'],
|
||||
['0.000', 'string'],
|
||||
['-0.000', 'string'],
|
||||
[new BcMath\Number('0'), 'object'],
|
||||
[new BcMath\Number('-0'), 'object'],
|
||||
[new BcMath\Number('0.000'), 'object'],
|
||||
[new BcMath\Number('-0.000'), 'object'],
|
||||
];
|
||||
|
||||
foreach ($values1 as $value1) {
|
||||
$num = new BcMath\Number($value1);
|
||||
|
||||
foreach ($values2 as [$value2, $type]) {
|
||||
echo "{$value1} and {$value2}: {$type}\n";
|
||||
echo "div: ";
|
||||
try {
|
||||
$num->div($value2);
|
||||
echo "NG\n";
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage() === 'Division by zero' ? 'OK' :'NG';
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
echo "mod: ";
|
||||
try {
|
||||
$num->mod($value2);
|
||||
echo "NG\n";
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage() === 'Modulo by zero' ? 'OK' :'NG';
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
echo "divmod: ";
|
||||
try {
|
||||
$num->divmod($value2);
|
||||
echo "NG\n";
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage() === 'Division by zero' ? 'OK' :'NG';
|
||||
echo "\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
100 and 0: int
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0: int
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and -0: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0.000: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and -0.000: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0.000: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
100 and 0.000: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0: int
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0: int
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and -0: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0.000: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and -0.000: string
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0.000: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
||||
|
||||
-100 and 0.000: object
|
||||
div: OK
|
||||
mod: OK
|
||||
divmod: OK
|
226
ext/bcmath/tests/number/methods/divmod.phpt
Normal file
226
ext/bcmath/tests/number/methods/divmod.phpt
Normal file
|
@ -0,0 +1,226 @@
|
|||
--TEST--
|
||||
BcMath\Number divmod()
|
||||
--EXTENSIONS--
|
||||
bcmath
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$values1 = ['100.012', '-100.012'];
|
||||
|
||||
$values2 = [
|
||||
[100, 'int'],
|
||||
[-30, 'int'],
|
||||
['-20', 'string'],
|
||||
['0.01', 'string'],
|
||||
['-0.40', 'string'],
|
||||
[new BcMath\Number('80.3'), 'object'],
|
||||
[new BcMath\Number('-50.6'), 'object'],
|
||||
];
|
||||
|
||||
foreach ($values1 as $value1) {
|
||||
$num = new BcMath\Number($value1);
|
||||
|
||||
foreach ($values2 as [$value2, $type]) {
|
||||
echo "{$value1} divmod {$value2}: {$type}\n";
|
||||
[$quot, $rem] = $num->divmod($value2);
|
||||
var_dump($quot, $rem);
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
100.012 divmod 100: int
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(1) "1"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(5) "0.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
100.012 divmod -30: int
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(2) "-3"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#7 (2) {
|
||||
["value"]=>
|
||||
string(6) "10.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
100.012 divmod -20: string
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(2) "-5"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(5) "0.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
100.012 divmod 0.01: string
|
||||
object(BcMath\Number)#7 (2) {
|
||||
["value"]=>
|
||||
string(5) "10001"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(5) "0.002"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
100.012 divmod -0.40: string
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(4) "-250"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(5) "0.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
100.012 divmod 80.3: object
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(1) "1"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#7 (2) {
|
||||
["value"]=>
|
||||
string(6) "19.712"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
100.012 divmod -50.6: object
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(2) "-1"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(6) "49.412"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod 100: int
|
||||
object(BcMath\Number)#3 (2) {
|
||||
["value"]=>
|
||||
string(2) "-1"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(6) "-0.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod -30: int
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(1) "3"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(7) "-10.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod -20: string
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(1) "5"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#3 (2) {
|
||||
["value"]=>
|
||||
string(6) "-0.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod 0.01: string
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(6) "-10001"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(6) "-0.002"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod -0.40: string
|
||||
object(BcMath\Number)#3 (2) {
|
||||
["value"]=>
|
||||
string(3) "250"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(6) "-0.012"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod 80.3: object
|
||||
object(BcMath\Number)#4 (2) {
|
||||
["value"]=>
|
||||
string(2) "-1"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#5 (2) {
|
||||
["value"]=>
|
||||
string(7) "-19.712"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
||||
|
||||
-100.012 divmod -50.6: object
|
||||
object(BcMath\Number)#6 (2) {
|
||||
["value"]=>
|
||||
string(1) "1"
|
||||
["scale"]=>
|
||||
int(0)
|
||||
}
|
||||
object(BcMath\Number)#3 (2) {
|
||||
["value"]=>
|
||||
string(7) "-49.412"
|
||||
["scale"]=>
|
||||
int(3)
|
||||
}
|
43
ext/bcmath/tests/number/methods/divmod_with_scale.phpt
Normal file
43
ext/bcmath/tests/number/methods/divmod_with_scale.phpt
Normal file
|
@ -0,0 +1,43 @@
|
|||
--TEST--
|
||||
BcMath\Number divmod() with scale
|
||||
--EXTENSIONS--
|
||||
bcmath
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$scales = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
|
||||
$values1 = ['100.012', '-100.012'];
|
||||
|
||||
$values2 = [
|
||||
[100, 'int'],
|
||||
[-30, 'int'],
|
||||
['-20', 'string'],
|
||||
['0.01', 'string'],
|
||||
['-0.40', 'string'],
|
||||
[new BcMath\Number('80.3'), 'object'],
|
||||
[new BcMath\Number('-50.6'), 'object'],
|
||||
];
|
||||
|
||||
foreach ($scales as $scale) {
|
||||
foreach ($values1 as $value1) {
|
||||
$num = new BcMath\Number($value1);
|
||||
|
||||
foreach ($values2 as [$value2, $type]) {
|
||||
[$func_quot, $func_rem] = bcdivmod($value1, (string) $value2, $scale);
|
||||
[$method_quot, $method_rem] = $num->divmod($value2, $scale);
|
||||
if ($method_quot->compare($func_quot) !== 0) {
|
||||
echo "Quot is incorrect.\n";
|
||||
var_dump($value1, $value2, $scale, $func_quot, $method_quot);
|
||||
}
|
||||
if ($method_rem->compare($func_rem) !== 0) {
|
||||
echo "Rem is incorrect.\n";
|
||||
var_dump($value1, $value2, $scale, $func_rem, $method_rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo 'done!';
|
||||
?>
|
||||
--EXPECT--
|
||||
done!
|
Loading…
Add table
Add a link
Reference in a new issue