Bug #78294 [Com]: Unexpected lose equality result
| From: | danack@php.net | Date: | Mon, 15 Jul 2019 12:59:28 +0000 |
| Subject: | Bug #78294 [Com]: Unexpected lose equality result | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-221784@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78294&edit=1
ID: 78294
Comment by: danack@php.net
Reported by: iuli dot butuc at yahoo dot com
Summary: Unexpected lose equality result
Status: Not a bug
Type: Bug
Package: *Math Functions
Operating System: Windows 10
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
To expand on what Dave said, 201905025815311.33 isn't representable as a floating point number.
When you try to create a floating point number with that value, it will be rounded to end either in
.32 or .34 depending on various things.
You can see that for yourself here:
https://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html
"php should not have any trouble working with these numbers."
It has no more trouble than comes naturally with using floating point numbers.
Previous Comments:
------------------------------------------------------------------------
[2019-07-15 12:54:00] daverandom@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
This is simply due to floating point precision errors, as you have observed.
PHP stores all floats as doubles, and comparisons are done as they would be in C - i.e. $float1 ==
$float2 in PHP is mapped directly to float1 == float2 in C.
There's nothing that PHP can/will do to change/improve this behaviour.
As a side note, the strings are not actually stored in memory as floats, however valid numeric
strings are converted to numbers for comparisons. Whether this is the "correct" behaviour
is debatable, however the debate would be purely academic as it isn't likely to change any time
soon - it would be a large BC break to do so, and the behaviour is actually useful considering that
PHP deals with stringly-typed data a lot (e.g. $_GET, $_POST and friends).
------------------------------------------------------------------------
[2019-07-15 12:45:39] iuli dot butuc at yahoo dot com
Description:
------------
Tested on php versions >= 5.6.
The lose equality result for '201905025815311.33' == '201905025815311.34' is
true for some reason i cannot identify. Needless to say using using the === operator fixes the
issue.
But the result for me is strange. Those strings are probably stored as floats in memory because they
have a perfect valid float format. But the float comparison for 201905025815311.33 ==
201905025815311.34 fails as well(evaluates to true).
Even if the numbers are rounded, it does not explain how can give the right result for
201905025815311.33 == 201905025815311.32 which should have the same "rounding" rules as
201905025815311.33 == 201905025815311.34. Maybe the 1.33 ending is the problem, but does not ring a
bell to me from a mathematical perspective.
Dumping the PHP_FLOAT_MAX constant on php versions that have it (7.2+) suggest that php should not
have any trouble working with these numbers.
Test script:
---------------
var_dump('201905025815311.33' == '201905025815311.34');
var_dump('201905025815311.33' == '201905025815311.32');
var_dump(201905025815311.33 == 201905025815311.34);
var_dump(201905025815311.33 == 201905025815311.32);
var_dump(201905025815311.32);
var_dump(201905025815311.33);
var_dump(201905025815311.34);
var_dump(PHP_FLOAT_MAX);
Expected result:
----------------
bool(false)
bool(false)
bool(false)
bool(false)
float(2.0190502581531E+14)
float(2.0190502581531E+14)
float(2.0190502581531E+14)
float(1.7976931348623E+308)
Actual result:
--------------
bool(true)
bool(false)
bool(true)
bool(false)
float(2.0190502581531E+14)
float(2.0190502581531E+14)
float(2.0190502581531E+14)
float(1.7976931348623E+308)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78294&edit=1