Bug #70804 [Asn->Csd]: Unary add on negative zero produces positive zero

[email protected]
Newsgroups php.bugs
Message-ID <[email protected]>
Edit report at https://bugs.php.net/bug.php?id=70804&edit=1

 ID:                 70804
 Updated by:         [email protected]
 Reported by:        davividal at gmail dot com
 Summary:            Unary add on negative zero produces positive zero
-Status:             Assigned
+Status:             Closed
 Type:               Bug
 Package:            *General Issues
 Operating System:   Linux
 PHP Version:        5.6.14
 Assigned To:        ajf
 Block user comment: N
 Private report:     N

 New Comment:

Automatic comment on behalf of [email protected]
Revision: http://git.php.net/?p=php-src.git;a=commit;h=42c8f5e91d4e4ec00d91506e986e3578a3695ee9
Log: Fix bug #70804


Previous Comments:
------------------------------------------------------------------------
[2015-12-19 02:11:19] [email protected]

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:03:35] [email protected]

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-11-05 19:00:00] 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-10-27 20:59:59] [email protected]

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-10-27 19:41:45] 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));



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=70804&edit=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.