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

From: Date: Sat, 19 Dec 2015 02:11:20 +0000
Subject: Bug #70804 [Asn]: Unary add on negative zero produces positive zero
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-198018@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70804&edit=1 ID: 70804 Updated by: ajf@php.net Reported by: davividal at gmail dot com -Summary: round(-0)=-0 but +round(-0)=0 +Summary: Unary add on negative zero produces positive zero Status: Assigned 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: I'm renaming the bug so it lines up with "Negating zero does not produce negative zero". The bug isn't really with round(). Previous Comments: ------------------------------------------------------------------------ [2015-12-19 02:03:35] 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-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] 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-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

« previous php.bugs (#198018) next »