Skip to content

Commit e35bdb4

Browse files
committed
Add fdiv() function
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.
1 parent 28ed73d commit e35bdb4

File tree

5 files changed

+109
-0
lines changed

5 files changed

+109
-0
lines changed

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ PHP 8.0 UPGRADE NOTES
318318
6. New Functions
319319
========================================
320320

321+
- Standard:
322+
. Added fdiv() method, which performs a floating-point devision under
323+
IEEE 754 semantics. Division by zero is considered well-defined and
324+
will return one of Inf, -Inf or NaN.
325+
321326
========================================
322327
7. New Classes and Interfaces
323328
========================================

ext/standard/basic_functions.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_fmod, 0)
11431143
ZEND_ARG_INFO(0, y)
11441144
ZEND_END_ARG_INFO()
11451145

1146+
ZEND_BEGIN_ARG_INFO(arginfo_fdiv, 0)
1147+
ZEND_ARG_INFO(0, dividend)
1148+
ZEND_ARG_INFO(0, divisor)
1149+
ZEND_END_ARG_INFO()
1150+
11461151
ZEND_BEGIN_ARG_INFO(arginfo_intdiv, 0)
11471152
ZEND_ARG_INFO(0, dividend)
11481153
ZEND_ARG_INFO(0, divisor)
@@ -1933,6 +1938,7 @@ static const zend_function_entry basic_functions[] = { /* {{{ */
19331938
PHP_FE(base_convert, arginfo_base_convert)
19341939
PHP_FE(number_format, arginfo_number_format)
19351940
PHP_FE(fmod, arginfo_fmod)
1941+
PHP_FE(fdiv, arginfo_fdiv)
19361942
PHP_FE(intdiv, arginfo_intdiv)
19371943
#ifdef HAVE_INET_NTOP
19381944
PHP_RAW_NAMED_FE(inet_ntop, zif_inet_ntop, arginfo_inet_ntop)

ext/standard/math.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,25 @@ PHP_FUNCTION(fmod)
13001300
}
13011301
/* }}} */
13021302

1303+
/* {{{ proto float fdiv(float dividend, float divisor)
1304+
Perform floating-point division of dividend / divisor
1305+
with IEEE-754 semantics for division by zero. */
1306+
#ifdef __clang__
1307+
__attribute__((no_sanitize("float-divide-by-zero")))
1308+
#endif
1309+
PHP_FUNCTION(fdiv)
1310+
{
1311+
double dividend, divisor;
1312+
1313+
ZEND_PARSE_PARAMETERS_START(2, 2)
1314+
Z_PARAM_DOUBLE(dividend)
1315+
Z_PARAM_DOUBLE(divisor)
1316+
ZEND_PARSE_PARAMETERS_END();
1317+
1318+
RETURN_DOUBLE(dividend / divisor);
1319+
}
1320+
/* }}} */
1321+
13031322
/* {{{ proto int intdiv(int dividend, int divisor)
13041323
Returns the integer quotient of the division of dividend by divisor */
13051324
PHP_FUNCTION(intdiv)

ext/standard/php_math.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ PHP_FUNCTION(octdec);
5959
PHP_FUNCTION(base_convert);
6060
PHP_FUNCTION(number_format);
6161
PHP_FUNCTION(fmod);
62+
PHP_FUNCTION(fdiv);
6263
PHP_FUNCTION(deg2rad);
6364
PHP_FUNCTION(rad2deg);
6465
PHP_FUNCTION(intdiv);

ext/standard/tests/math/fdiv.phpt

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
--TEST--
2+
fdiv() function
3+
--FILE--
4+
<?php
5+
6+
var_dump(fdiv(10, 3));
7+
var_dump(fdiv(10., 3.));
8+
var_dump(fdiv(-10., 2.5));
9+
var_dump(fdiv(10., -2.5));
10+
echo "\n";
11+
var_dump(fdiv(10., 0.));
12+
var_dump(fdiv(10., -0.));
13+
var_dump(fdiv(-10., 0.));
14+
var_dump(fdiv(-10., -0.));
15+
echo "\n";
16+
var_dump(fdiv(INF, 0.));
17+
var_dump(fdiv(INF, -0.));
18+
var_dump(fdiv(-INF, 0.));
19+
var_dump(fdiv(-INF, -0.));
20+
echo "\n";
21+
var_dump(fdiv(0., 0.));
22+
var_dump(fdiv(0., -0.));
23+
var_dump(fdiv(-0., 0.));
24+
var_dump(fdiv(-0., -0.));
25+
echo "\n";
26+
var_dump(fdiv(INF, INF));
27+
var_dump(fdiv(INF, -INF));
28+
var_dump(fdiv(-INF, INF));
29+
var_dump(fdiv(-INF, -INF));
30+
echo "\n";
31+
var_dump(fdiv(0., INF));
32+
var_dump(fdiv(0., -INF));
33+
var_dump(fdiv(-0., INF));
34+
var_dump(fdiv(-0., -INF));
35+
echo "\n";
36+
var_dump(fdiv(NAN, NAN));
37+
var_dump(fdiv(INF, NAN));
38+
var_dump(fdiv(0., NAN));
39+
var_dump(fdiv(NAN, INF));
40+
var_dump(fdiv(NAN, 0.));
41+
42+
?>
43+
--EXPECT--
44+
float(3.3333333333333)
45+
float(3.3333333333333)
46+
float(-4)
47+
float(-4)
48+
49+
float(INF)
50+
float(-INF)
51+
float(-INF)
52+
float(INF)
53+
54+
float(INF)
55+
float(-INF)
56+
float(-INF)
57+
float(INF)
58+
59+
float(NAN)
60+
float(NAN)
61+
float(NAN)
62+
float(NAN)
63+
64+
float(NAN)
65+
float(NAN)
66+
float(NAN)
67+
float(NAN)
68+
69+
float(0)
70+
float(-0)
71+
float(-0)
72+
float(0)
73+
74+
float(NAN)
75+
float(NAN)
76+
float(NAN)
77+
float(NAN)
78+
float(NAN)

0 commit comments

Comments
 (0)