php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70804 Unary add on negative zero produces positive zero
Submitted: 2015-10-27 19:41 UTC Modified: 2015-12-19 02:11 UTC
From: davividal at gmail dot com Assigned: ajf (profile)
Status: Closed Package: *General Issues
PHP Version: 5.6.14 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: davividal at gmail dot com
New email:
PHP Version: OS:

 

 [2015-10-27 19:41 UTC] davividal at gmail dot com
Description:
------------
Given a negative number, it's possible to turn it into positive by just putting a positive sign in front of it.

Test script:
---------------
var_dump(round(-1e-99));
var_dump(+round(-1e-99));


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-27 20:59 UTC] requinix@php.net
-Summary: Positive * Negative = Positive +Summary: round(-0)=-0 but +round(-0)=0
 [2015-10-27 20:59 UTC] requinix@php.net
Changed the summary. I take it you were originally seeing this with some multiplication?

It's not that the plus sign causes it to become positive. The same thing happens with a negative sign too: PHP recognizes the zero and forces it to be positive.

I don't know if this counts as a bug but it certainly could qualify as a request: while -0 is a legitimate (though unusual) floating-point number, I think that round(-0) should also force it to be positive.
 [2015-11-05 19:00 UTC] davividal at gmail dot com
After a bunch of operations I saw something like:

<?php
$var = round($foo - $bar);
$var = +$var;
?>

And wondered what was going on.

As for your statement that round() should turn the number into positive: that's what Ruby does, but not what Python does (I only tested on these 2). So I don't know what the correct behaviour should be here.

>>> foo = -1e-99
>>> round(foo)
-0.0
>>> +round(foo)
-0.0

irb(main):001:0> foo = -1e-99
=> -1.0e-99
irb(main):002:0> foo.round
=> 0
irb(main):003:0> +foo.round
=> 0

What I do know: +(-x) should be equal to -x. :)
 [2015-12-19 02:03 UTC] ajf@php.net
-Assigned To: +Assigned To: ajf
 [2015-12-19 02:03 UTC] ajf@php.net
I think this is a related problem to bug #52355: https://bugs.php.net/bug.php?id=52355

Unary plus in PHP is actually transformed by the compiler into adding zero. So +$a is effectively (0 + $a). Similarly, unary minus was transformed into subtracting from zero, so -$a is effectively (0 - $a).

However, it turned out that -$a and (0 - $a) don't behave exactly the same for floating-point in one specific case: negative zero. Evidently, this is also true for +$a and (0 + $a).

My solution for the -$a case was to transform it into (-1 * $a) instead, and that fixed that issue. It looks like we can use the same approach here, and +$a into (1 * $a), which doesn't mangle negative zero:

    $ sapi/cli/php -r 'var_dump(1 * round(-1e-99));'
    float(-0)

So, I'll write a patch to do this.
 [2015-12-19 02:11 UTC] ajf@php.net
-Summary: round(-0)=-0 but +round(-0)=0 +Summary: Unary add on negative zero produces positive zero
 [2015-12-19 02:11 UTC] ajf@php.net
I'm renaming the bug so it lines up with "Negating zero does not produce negative zero". The bug isn't really with round().
 [2015-12-19 02:35 UTC] ajf@php.net
Automatic comment on behalf of ajf@ajf.me
Revision: http://git.php.net/?p=php-src.git;a=commit;h=42c8f5e91d4e4ec00d91506e986e3578a3695ee9
Log: Fix bug #70804
 [2015-12-19 02:35 UTC] ajf@php.net
-Status: Assigned +Status: Closed
 [2015-12-19 02:35 UTC] ajf@php.net
Automatic comment on behalf of ajf@ajf.me
Revision: http://git.php.net/?p=php-src.git;a=commit;h=42c8f5e91d4e4ec00d91506e986e3578a3695ee9
Log: Fix bug #70804
 [2016-07-20 11:34 UTC] davey@php.net
Automatic comment on behalf of ajf@ajf.me
Revision: http://git.php.net/?p=php-src.git;a=commit;h=42c8f5e91d4e4ec00d91506e986e3578a3695ee9
Log: Fix bug #70804
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC