]> granicus.if.org Git - php/commitdiff
Add fdiv() function
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 2 Oct 2019 13:06:09 +0000 (15:06 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 11 Oct 2019 14:36:11 +0000 (16:36 +0200)
The fdiv() function is part of the fmod() / intdiv() family. It
implements a floating-point division with IEEE-754 semantics.
That is, division by zero is considered well-defined and does not
trigger any kind of diagnostic. Instead one of INF, -INF or NAN
will be returned, depending on the case.

This is in preparation for throwing DivisionByZeroError from the
standard division operator.

UPGRADING
ext/standard/basic_functions.c
ext/standard/math.c
ext/standard/php_math.h
ext/standard/tests/math/fdiv.phpt [new file with mode: 0644]

index 7d26e2201904cf2529b547b295f3cec5b7deeeca..7783f92f9b9d1d62afefbc417dadfd91a3a148f6 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -318,6 +318,11 @@ PHP 8.0 UPGRADE NOTES
 6. New Functions
 ========================================
 
+- Standard:
+  . Added fdiv() method, which performs a floating-point devision under
+    IEEE 754 semantics. Division by zero is considered well-defined and
+    will return one of Inf, -Inf or NaN.
+
 ========================================
 7. New Classes and Interfaces
 ========================================
index 01071dd244ff1cd36f773dd3b10216fd32297101..1c3ad1d2bd2ccc5800a83369c786c088459ea588 100755 (executable)
@@ -1143,6 +1143,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_fmod, 0)
        ZEND_ARG_INFO(0, y)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO(arginfo_fdiv, 0)
+       ZEND_ARG_INFO(0, dividend)
+       ZEND_ARG_INFO(0, divisor)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO(arginfo_intdiv, 0)
        ZEND_ARG_INFO(0, dividend)
        ZEND_ARG_INFO(0, divisor)
@@ -1933,6 +1938,7 @@ static const zend_function_entry basic_functions[] = { /* {{{ */
        PHP_FE(base_convert,                                                                                                    arginfo_base_convert)
        PHP_FE(number_format,                                                                                                   arginfo_number_format)
        PHP_FE(fmod,                                                                                                                    arginfo_fmod)
+       PHP_FE(fdiv,                                                                                                                    arginfo_fdiv)
        PHP_FE(intdiv,                                                                                                                  arginfo_intdiv)
 #ifdef HAVE_INET_NTOP
        PHP_RAW_NAMED_FE(inet_ntop,             zif_inet_ntop,                                                          arginfo_inet_ntop)
index b2e56f5a272f4cc0ff163464ab5e2fa10d8bb649..be3516400a19131a65a7ed2710bc4843f7915ff9 100644 (file)
@@ -1300,6 +1300,25 @@ PHP_FUNCTION(fmod)
 }
 /* }}} */
 
+/* {{{ proto float fdiv(float dividend, float divisor)
+   Perform floating-point division of dividend / divisor
+   with IEEE-754 semantics for division by zero. */
+#ifdef __clang__
+__attribute__((no_sanitize("float-divide-by-zero")))
+#endif
+PHP_FUNCTION(fdiv)
+{
+       double dividend, divisor;
+
+       ZEND_PARSE_PARAMETERS_START(2, 2)
+               Z_PARAM_DOUBLE(dividend)
+               Z_PARAM_DOUBLE(divisor)
+       ZEND_PARSE_PARAMETERS_END();
+
+       RETURN_DOUBLE(dividend / divisor);
+}
+/* }}} */
+
 /* {{{ proto int intdiv(int dividend, int divisor)
    Returns the integer quotient of the division of dividend by divisor */
 PHP_FUNCTION(intdiv)
index 39751a7f8963d8d710616bff4c9412aa4fba2788..e85fd120f2c6c775284b60a14ed6fb4812993999 100644 (file)
@@ -59,6 +59,7 @@ PHP_FUNCTION(octdec);
 PHP_FUNCTION(base_convert);
 PHP_FUNCTION(number_format);
 PHP_FUNCTION(fmod);
+PHP_FUNCTION(fdiv);
 PHP_FUNCTION(deg2rad);
 PHP_FUNCTION(rad2deg);
 PHP_FUNCTION(intdiv);
diff --git a/ext/standard/tests/math/fdiv.phpt b/ext/standard/tests/math/fdiv.phpt
new file mode 100644 (file)
index 0000000..dd50cfd
--- /dev/null
@@ -0,0 +1,78 @@
+--TEST--
+fdiv() function
+--FILE--
+<?php
+
+var_dump(fdiv(10, 3));
+var_dump(fdiv(10., 3.));
+var_dump(fdiv(-10., 2.5));
+var_dump(fdiv(10., -2.5));
+echo "\n";
+var_dump(fdiv(10., 0.));
+var_dump(fdiv(10., -0.));
+var_dump(fdiv(-10., 0.));
+var_dump(fdiv(-10., -0.));
+echo "\n";
+var_dump(fdiv(INF, 0.));
+var_dump(fdiv(INF, -0.));
+var_dump(fdiv(-INF, 0.));
+var_dump(fdiv(-INF, -0.));
+echo "\n";
+var_dump(fdiv(0., 0.));
+var_dump(fdiv(0., -0.));
+var_dump(fdiv(-0., 0.));
+var_dump(fdiv(-0., -0.));
+echo "\n";
+var_dump(fdiv(INF, INF));
+var_dump(fdiv(INF, -INF));
+var_dump(fdiv(-INF, INF));
+var_dump(fdiv(-INF, -INF));
+echo "\n";
+var_dump(fdiv(0., INF));
+var_dump(fdiv(0., -INF));
+var_dump(fdiv(-0., INF));
+var_dump(fdiv(-0., -INF));
+echo "\n";
+var_dump(fdiv(NAN, NAN));
+var_dump(fdiv(INF, NAN));
+var_dump(fdiv(0., NAN));
+var_dump(fdiv(NAN, INF));
+var_dump(fdiv(NAN, 0.));
+
+?>
+--EXPECT--
+float(3.3333333333333)
+float(3.3333333333333)
+float(-4)
+float(-4)
+
+float(INF)
+float(-INF)
+float(-INF)
+float(INF)
+
+float(INF)
+float(-INF)
+float(-INF)
+float(INF)
+
+float(NAN)
+float(NAN)
+float(NAN)
+float(NAN)
+
+float(NAN)
+float(NAN)
+float(NAN)
+float(NAN)
+
+float(0)
+float(-0)
+float(-0)
+float(0)
+
+float(NAN)
+float(NAN)
+float(NAN)
+float(NAN)
+float(NAN)