Re: Spaceship and NaNs
| From: | Stanislav Malyshev | Date: | Mon, 15 Jun 2015 20:44:28 +0000 |
| Subject: | Re: Spaceship and NaNs | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-86678@lists.php.net to get a copy of this message | ||
Hi!
> I found a problem with spaceship operator.
> It doesn't define result for comparison with NaN.
>
> $ sapi/cli/php -r 'var_dump(sqrt(-1) <=> 0);'
> int(-1)
> $ sapi/cli/php -r 'var_dump(0 <=> sqrt(-1));'
> int(-1)
>
> $ sapi/cli/php -r 'var_dump(0 < sqrt(-1));'
> bool(false)
>
> all other comparison operators return "false" as well.
I think <=> is defined as:
1. if < returns true, then negative
2. if == returns true, then 0
3. otherwise, positive
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#relational-operators
So the result here is wrong I assume. I suspect this is the consequence
of how compare_function treats IS_DOUBLE - it first subtracts them
(which produces NaN) and then does ZEND_NORMALIZE_BOOL - which is:
#define ZEND_NORMALIZE_BOOL(n) \
((n) ? (((n)>0) ? 1 : -1) : 0)
Since NaN > 0 is false, what we get is -1. I guess we should add check
for NaN in either ZEND_NORMALIZE_BOOL or comparison routine, but not
sure what comparing to NaN should produce... Always false? AFAIK NaN is
not equal to NaN so that may be the best option.
The individual comparison operators already return false with NaN but I
suspect not for the right reasons...
--
Stas Malyshev
smalyshev@gmail.com