Hi Bob,

> On 29 Jun 2015, at 16:54, Bob Weinand <bobw...@hotmail.com> wrote:
> 
> I would like to bring this topic back up, as there were users confused with 
> it and it's absolutely not consistent what we have now.
> See also https://bugs.php.net/bug.php?id=69957 (As I thought it was 
> non-intentional, I went ahead and "fixed" it, was reverted later, hence 
> discussing that now here.)
> 
> So, looks like there was some quick decisions and discussion I totally had 
> missed.
> What we have now is:
> 
>> Am 03.04.2015 um 23:13 schrieb Dmitry Stogov <dmi...@zend.com>:
>> 
>> So the summary:
>> 
>> 1) division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
>> evaluation is disabled.
>> 
>> 3) Modulo by zero produces Exception.Compile-time evaluation is disabled.
> 
> Why? Why do we change the one but not the other?
> 
> Why does 0 % 0 throw an Exception, but 0 / 0 NAN?
> Why does 1 % 0 throw an Exception, but 1 / 0 INF?
> 
> I'd like to either properly return 0, INF or NAN in both cases or in none.
> 
> Having different rules for so similar operations is non-sense, I think. It 
> just is inconsistent and causes confusion.

Those operations are not as similar as you think!

In PHP, the complement of % isn’t /, it’s intdiv(). intdiv() takes an integer 
divided and divisor, and produces an integer quotient. % also takes an integer 
dividend and divisor, but produces an integer remainder. intdiv() and % work 
with integer-only inputs and always produce integer outputs.

/, on the other hand, takes an integer or float dividend and divisor, and 
produces an integer or float fractional result. It might as well work only on 
floats and always produce floats, really, given that it behaves the same as if 
it did.

So intdiv() and % work on integers, and / works on integers and floats. This 
informs how they handle certain error cases.

For integer division and modulo (PHP’s intdiv() and %), the accepted way to 
handle division by zero is to produce an error. There’s no correct or useful 
result you can produce. In PHP, we used to produce FALSE here, which is a 
different type (boolean). I don’t think that was a good idea because of PHP’s 
weak typing. If you use FALSE in some other arithmetic operation, it’ll be 
coerced to zero, and produce weird results from other operations. Sure, there’s 
an E_WARNING produced, but your code keeps running and produces garbage. So, 
throwing an exception is safer and brings PHP into line with established 
practice in other programming languages.

For floating-point division (PHP’s /), on the other hand, errors are usually 
handled differently. IEEE 754 defines special error values we can produce: 
+Infinity, -Infinity and NaN. These are still values of the float type, but 
they’re not normal numbers. They flow through floating-point operations in a 
well-defined manner. For example, if you do anything with a NaN and a NaN, you 
get a NaN, while if you divide by zero, you get ±Infinity, and if you divide by 
Infinity, you get ±0. Again, PHP used to produce FALSE here, which has the 
problems described earlier. ±Infinity and NaN, on the other hand, flow properly 
through later arithmetic operations. If the error affects your result, it will 
most likely be obvious, because it’ll be ±0, ±Infinity, or NaN. Yes, you result 
is garbage, but it’s at least obviously so. And, like with the integer 
behaviour, this brings PHP into line with established practice.

tl;dr: intdiv() and % have matching behaviour because they work with integers 
and that’s what’s usually does for them, / has different behaviour because it 
works with floats and that’s what’s done for them.

I hope that makes sense.

--
Andrea Faulds
http://ajf.me/





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to