php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #77778 0.0 is falsy but docs do not say -0.0 is falsy too
Submitted: 2019-03-21 16:55 UTC Modified: 2019-04-04 08:38 UTC
From: lewisje at alumni dot iu dot edu Assigned: salathe (profile)
Status: Closed Package: *General Issues
PHP Version: Irrelevant OS: CentOS 6
Private report: No CVE-ID: None
 [2019-03-21 16:55 UTC] lewisje at alumni dot iu dot edu
Description:
------------
---
From manual page: https://php.net/language.types.boolean
---
Among the values listed as falsy is "the float 0.0 (zero)", but the float -0.0 is not listed; however, it is both falsy and distinct from 0.0: As ought to be pointed out in https://php.net/language.types.float, IEEE-754 floating-point arithmetic includes distinct 0.0 and -0.0 values; even though they will be treated as equal under strict equality, 1/0.0 is INF, while 1/-0.0 is -INF, again as in the IEEE-754 specification.

Test script:
---------------
<?php
var_dump(1/0.0);        // float(INF)
var_dump(1/-0.0);       // float(-INF)
var_dump(-0.0 === 0.0); // bool(true)
var_dump((bool)-0.0);   // bool(false)
?>

Expected result:
----------------
Based on the literal documentation, (bool)-0.0 ought to be true.

Actual result:
--------------
(bool)-0.0 is false, and as the other statements show, -0.0 can be distinguished from 0.0, which means that it is another falsy value.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-03-21 18:14 UTC] requinix@php.net
-Summary: -0.0 and 0.0 are distinct values. +Summary: 0.0 is falsy but docs do not say -0.0 is falsy too -Package: Documentation problem +Package: *General Issues
 [2019-03-21 18:14 UTC] requinix@php.net
If 0.0 and -0.0 are strictly identical then under what logic should (bool)0.0 be false and (bool)-0.0 be true?

Seems silly to me that the docs should have to point out that both 0.0 and -0.0 are false, but I suppose it's an easy enough edit that it's not worth arguing about.
 [2019-03-21 18:42 UTC] lewisje at alumni dot iu dot edu
As I showed above, even though -0.0 and 0.0 show as equal under strict equality, they are distinct values, because 1/-0.0 and 1/0.0 are the respective distinct values -INF and INF; this is by design, to quote from Section 5.7 of ANSI/IEEE Std 754-1985: http://www.validlab.com/754R/web-2008/standards/754.pdf

> Comparisons shall ignore the sign of zero (so +0 = –0).

Sections 7.2 and 6.3 together imply that it is by design that 1/0.0 is INF and 1/-0.0 is -INF.

---
It does seem like a nitpick, but it just stuck out to me after I had noticed a similar distinction in Ecmascript (Crockford and many other expositors don't make a distinction, while the Definitive Guide by Flanagan did make it); also, the way I mentioned earlier to be able to distinguish the positive and negative zero floats is exactly what is done in the polyfill for Object.is from ES6. (I'm not saying here that it's vital for PHP to have some built-in function that distinguishes -0.0 from 0.0 and compares NAN as equal to itself, the way Object.is does.)
 [2019-03-21 19:06 UTC] requinix@php.net
> Sections 7.2 and 6.3 together imply that it is by design that 1/0.0 is INF and 1/-0.0 is -INF.
Right. They could have said $n/0.0 == $n/-0.0 == NAN or DIV or something but they chose the arguably more useful +INF/-INF. It also means that according to IEEE +0.0 and -0.0 are treated inconsistently: equal in one place, not equal in another.

Anyways, PHP does not distinguish between +0.0 and -0.0 because the IEEE-ness of PHP's floats is besides the point. In fact there have been bugs where PHP produces an unexpected "-0.0" which were fixed so it was "0.0". And everyone agrees that +0.0 === -0.0 should be true. Which is why saying that (bool)-0.0 should be true doesn't make sense - it should be false, as it already is.

Which brings this to a question of documentation: whether or not to state that yes, in fact, -0.0 is falsy too. But like I said, an easy enough edit.
 [2019-03-21 19:26 UTC] salathe@php.net
Automatic comment from SVN on behalf of salathe
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=347033
Log: negative zero is falsy (fix bug #77778)
 [2019-03-21 19:26 UTC] salathe@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.
 [2019-03-21 19:26 UTC] salathe@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: salathe
 [2019-03-21 19:30 UTC] salathe@php.net
Automatic comment on behalf of salathe
Revision: http://git.php.net/?p=doc/en.git;a=commit;h=096a3dce5d92652947579249761728eb4e48cdde
Log: negative zero is falsy (fix bug #77778)
 [2019-03-27 23:40 UTC] lewisje at alumni dot iu dot edu
I just saw the new documentation page, and I should mention that there is no distinction between -0 and 0 for *integer* arithmetic, even though floating-point makes such a distinction:

<?php
var_dump(1/-0); // float(INF)
var_dump(1/0);  // float(INF)
?>
 [2019-03-27 23:53 UTC] salathe@php.net
Thanks for mentioning it, but to what end: do you want the -0 example removed?
 [2019-04-04 08:37 UTC] lewisje at alumni dot iu dot edu
Yes, because there is not an integer -0 that is distinct from the integer 0; also, I don't know whether this is out of scope for the bug, but https://php.net/function.empty does not mention that the float -0.0 is treated as empty, even though it is:

<?php
var_dump(-0.0); // bool(true)
?>
 [2019-04-04 08:38 UTC] lewisje at alumni dot iu dot edu
Sorry, that code example was supposed to be this:

<?php
var_dump(empty(-0.0)); // bool(true)
?>
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Aug 20 05:01:27 2019 UTC