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