Skip to content

[RFC] Add clamp function #7191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4d5c4fb
Add clamp function
thinkverse Apr 18, 2021
7d6ae1f
Fix clamp error message
thinkverse Apr 18, 2021
321afb1
Fix clamp return value
thinkverse Apr 18, 2021
3d0a6e8
Add basic test for clamp function
thinkverse Apr 18, 2021
4e2d3ae
Fix basic clamp test
thinkverse Apr 18, 2021
5c80a09
Refactor clamp function basic tests
thinkverse Apr 18, 2021
fc5342d
Fix clamp basic test 1
thinkverse Apr 18, 2021
4129f61
Merge branch 'master' into feat/math-clamp
thinkverse Apr 20, 2021
279c073
Fix clamp function return type
thinkverse Apr 20, 2021
bc7aacb
Fix clamp function error message
thinkverse Apr 20, 2021
873f323
Merge master
thinkverse Apr 25, 2021
48195b3
Merge branch 'master' into feat/math-clamp
thinkverse Jun 20, 2021
f46f20f
Add clamp exception to test case
thinkverse Jun 22, 2021
59e64cf
Refactor `clamp` to use zend_compare
thinkverse Jun 22, 2021
1780dd1
Remove unnecessary return value check
thinkverse Jun 22, 2021
9c887ec
Update clamp test suite
thinkverse Jun 23, 2021
5359f34
Fix clamp test suite names
thinkverse Jun 23, 2021
20a25bc
clamp now handles NAN values
thinkverse Jul 3, 2021
c16076b
Update clamp tests
thinkverse Jul 3, 2021
696edac
Fix wording, NaN -> NAN
thinkverse Jul 3, 2021
641e2f4
Fix clamp NAN behaviour
thinkverse Jul 6, 2021
bae3315
Fix clamp not returning NAN when passed to ``
thinkverse Jul 6, 2021
1ae79ba
Switch from RETURN_COPY to RETURN_COPY_VALUE
thinkverse Jul 6, 2021
388b2b5
Regenerate basic functions arginfo
thinkverse Jul 6, 2021
8b5bb09
Revert "Regenerate basic functions arginfo"
thinkverse Jul 6, 2021
1dca2f4
Merge branch 'master' into feat/math-clamp
thinkverse Jul 6, 2021
1dad42f
Regenerate basic functions arginfo
thinkverse Jul 7, 2021
2b46215
Merge branch 'master' into feat/math-clamp
thinkverse Apr 18, 2022
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
2 changes: 2 additions & 0 deletions ext/standard/basic_functions.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,8 @@ function mail(string $to, string $subject, string $message, array|string $additi

function abs(int|float $num): int|float {}

function clamp(int|float $num, int|float $min, int|float $max): int|float {}

function ceil(int|float $num): float {}

function floor(int|float $num): float {}
Expand Down
8 changes: 8 additions & 0 deletions ext/standard/basic_functions_arginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_abs, 0, 1, MAY_BE_LONG|MAY_BE_DO
ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_clamp, 0, 3, MAY_BE_LONG|MAY_BE_DOUBLE)
ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
ZEND_ARG_TYPE_MASK(0, min, MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
ZEND_ARG_TYPE_MASK(0, max, MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ceil, 0, 1, IS_DOUBLE, 0)
ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
ZEND_END_ARG_INFO()
Expand Down Expand Up @@ -2657,6 +2663,7 @@ ZEND_FUNCTION(link);
#endif
ZEND_FUNCTION(mail);
ZEND_FUNCTION(abs);
ZEND_FUNCTION(clamp);
ZEND_FUNCTION(ceil);
ZEND_FUNCTION(floor);
ZEND_FUNCTION(round);
Expand Down Expand Up @@ -3298,6 +3305,7 @@ static const zend_function_entry ext_functions[] = {
#endif
ZEND_FE(mail, arginfo_mail)
ZEND_FE(abs, arginfo_abs)
ZEND_FE(clamp, arginfo_clamp)
ZEND_FE(ceil, arginfo_ceil)
ZEND_FE(floor, arginfo_floor)
ZEND_FE(round, arginfo_round)
Expand Down
26 changes: 26 additions & 0 deletions ext/standard/math.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,32 @@ PHP_FUNCTION(abs)
}
/* }}} */

/* {{{ Return the given value if in range of min and max */
PHP_FUNCTION(clamp)
{
zval *zvalue, *zmin, *zmax;

ZEND_PARSE_PARAMETERS_START(3, 3)
Z_PARAM_NUMBER(zvalue)
Z_PARAM_NUMBER(zmin)
Z_PARAM_NUMBER(zmax)
ZEND_PARSE_PARAMETERS_END();

if (zend_compare(zmax, zmin) == -1) {
zend_argument_value_error(2, "cannot be greater than Argument #3 ($max)");
RETURN_THROWS();
}

if (zend_compare(zmax, zvalue) == -1) {
RETURN_COPY(zmax);
} else if (zend_compare(zmin, zvalue) == -1) {
RETURN_COPY(zvalue);
} else {
RETURN_COPY(zmin);
}
}
/* }}} */

/* {{{ Returns the next highest integer value of the number */
PHP_FUNCTION(ceil)
{
Expand Down
26 changes: 26 additions & 0 deletions ext/standard/tests/math/clamp_basic1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
Test clamp() function : basic functionality
--FILE--
<?php
echo "*** Testing clamp() : basic functionality - using integers ***\n";

var_dump(clamp(0, 1, 2));
var_dump(clamp(2, 1, 3));
var_dump(clamp(3, 1, 4));
var_dump(clamp(5, 1, 4));
var_dump(clamp(5, 1, 5));

try {
var_dump(clamp(5, 5, 1));
} catch (\ValueError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECTF--
*** Testing clamp() : basic functionality - using integers ***
int(1)
int(2)
int(3)
int(4)
int(5)
clamp(): Argument #2 ($min) cannot be greater than Argument #3 ($max)
26 changes: 26 additions & 0 deletions ext/standard/tests/math/clamp_basic2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
Test clamp() function : basic functionality
--FILE--
<?php
echo "*** Testing clamp() : basic functionality - using floats ***\n";

var_dump(clamp(0.0, 1.0, 2.0));
var_dump(clamp(1.5, 1.0, 2.0));
var_dump(clamp(2.0, 1.0, 2.5));
var_dump(clamp(3.0, 1.0, 2.5));
var_dump(clamp(0, 3.0, 3.5));

try {
var_dump(clamp(1, 3.5, 3.0));
} catch (\ValueError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECTF--
*** Testing clamp() : basic functionality - using floats ***
float(1)
float(1.5)
float(2)
float(2.5)
float(3)
clamp(): Argument #2 ($min) cannot be greater than Argument #3 ($max)