Bug #78073 [Nab]: echo fmod(25, 0.2); // 0.2, must be 0

From: Date: Mon, 27 May 2019 11:23:46 +0000
Subject: Bug #78073 [Nab]: echo fmod(25, 0.2); // 0.2, must be 0
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-221011@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78073&edit=1 ID: 78073 Updated by: cmb@php.net Reported by: e dot grinec at gmail dot com Summary: echo fmod(25, 0.2); // 0.2, must be 0 Status: Not a bug Type: Bug Package: *Math Functions Operating System: Windows 10 x64 PHP Version: 7.3.5 Assigned To: cmb Block user comment: N Private report: N New Comment: PHP's implementation of fmod() just forwards to C's fmod()[1]. If you think there is a bug in C's fmod(), please report it to the respective developers. Thanks. [1] <https://github.com/php/php-src/blob/php-7.3.6RC1/ext/standard/math.c#L1284-L1294> Previous Comments: ------------------------------------------------------------------------ [2019-05-27 10:54:43] e dot grinec at gmail dot com Why do you think, that correct answer on this expression abs(fmod(1, 0.1)) < abs(0.1); is true? ------------------------------------------------------------------------ [2019-05-27 10:43:16] e dot grinec at gmail dot com function fmod($x, $y) { if (!$y) { return NAN; } $q = $x / $y; $f = ($q < 0 ? 'ceil' : 'floor'); return $x - $f($q) * $y; } ------------------------------------------------------------------------ [2019-05-27 10:39:39] cmb@php.net Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://www.floating-point-gui.de/ Thank you for your interest in PHP. The magnitude of the result is smaller than the divisor, see <https://3v4l.org/ZlnYS>. ------------------------------------------------------------------------ [2019-05-27 09:58:56] e dot grinec at gmail dot com The following patch has been added/updated: Patch Name: patch.txt Revision: 1558951136 URL: https://bugs.php.net/patch-display.php?bug=78073&patch=patch.txt&revision=1558951136 ------------------------------------------------------------------------ [2019-05-27 09:51:43] e dot grinec at gmail dot com Description: ------------ --- From manual page: https://php.net/function.fmod --- PHP 5.2.x through PHP 7.3.2 still the same problem. Code: <?php echo fmod(-25, 0.2); // -0.2, should be 0 echo -25 - floor(-25/0.2) * 0.2; // 0, as it should be ?> Default installation of OSPanel (OpenServer 5.2.2) with default configuration of php.ini and etc in it. Documentation says: "Returns the floating point remainder of dividing the dividend (x) by the divisor (y). The remainder (r) is defined as: x = i * y + r, for some integer i. If y is non-zero, r has the same sign as x and a magnitude LESS than the magnitude of y." But r magnitude EQUAL to y. Solution: function fmod($x, $y){return echo $x - floor($x/$y) * $y;} Test script: --------------- <?php echo var_dump(fmod(21, 0.2) == 0); // bool(false) echo var_dump(fmod(1, 0.1) == 0); // bool(false) echo fmod(1, 0.1); // 0.1 echo fmod(1, 0.2); // 0.2 Expected result: ---------------- <?php echo var_dump(fmod(21, 0.2) == 0); // bool(true) echo var_dump(fmod(1, 0.1) == 0); // bool(true) echo fmod(1, 0.1); // 0 echo fmod(1, 0.2); // 0 Actual result: -------------- bool(false) bool(false) 0.1 0.2 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78073&edit=1

« previous php.bugs (#221011) next »