- Division by zero behavior in PHP is really inconsistent.
It emits WARNING and returns FALLE.
Note, that since PHP-5.6 division by zero may also occur in constant
expressions. They are compiled and evaluated only once (on first request)
and on next request WARNING is going to be hidden.
$ cat div.php
<?php
class C {
const T = 5 / 0;
}
var_dump(C::T);
?>
$ sapi/cgi/php-cgi -q -T 3 div.php
PHP Warning: Division by zero in
/home/dmitry/php/php-master/CGI-DEBUG/div.php on line 3
bool(false)
bool(false)
bool(false)
I propose to change this into fatal error for division by zero at
compile-time and exception a run-time.
- Very similar weird behavior was introduced for shift with negative
offsets. I also propose to change it in the same way (Fatal error at
compile-time, Exception in run-time).
Any thoughts? objections?
Thanks. Dmitry.
Hi Dmitry,
- Very similar weird behavior was introduced for shift with negative offsets. I also propose to change it in the same way (Fatal error at compile-time, Exception in run-time).
Any thoughts? objections?
For consistency with IEEE 754, shouldn't we produce INF
on a division by zero, at least for floats (but probably integers too because of weak typing)? I don't think producing a warning is an issue, but FALSE
isn't the right value to produce.
However there should be a compile-time solution. Maybe, if a division by zero happens, don't evaluate the expression at compile-time?
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi Dmitry,
- Very similar weird behavior was introduced for shift with negative offsets. I also propose to change it in the same way (Fatal error at compile-time, Exception in run-time).
Any thoughts? objections?
For consistency with IEEE 754, shouldn't we produce
INF
on a division by zero, at least for floats (but probably integers too because of weak typing)? I don't think producing a warning is an issue, butFALSE
isn't the right value to produce.
I agree with Andrea. Currently we do floating point division even if
both arguments are integers, and the correct behavior for a floating
point divide by zero is to produce an INF
or -INF.
Hi Dmitry,
- Very similar weird behavior was introduced for shift with negative offsets. I also propose to change it in the same way (Fatal error at compile-time, Exception in run-time).
Any thoughts? objections?
For consistency with IEEE 754, shouldn't we produce
INF
on a division by zero, at least for floats (but probably integers too because of weak typing)? I don't think producing a warning is an issue, butFALSE
isn't the right value to produce.I agree with Andrea. Currently we do floating point division even if
both arguments are integers, and the correct behavior for a floating
point divide by zero is to produce anINF
or -INF.
Well, correct as defined by IEEE 754 anyway.
Hi Dmitry,
- Very similar weird behavior was introduced for shift with negative
offsets. I also propose to change it in the same way (Fatal error at
compile-time, Exception in run-time).Any thoughts? objections?
For consistency with IEEE 754, shouldn't we produce
INF
on a division by
zero, at least for floats (but probably integers too because of weak
typing)? I don't think producing a warning is an issue, butFALSE
isn't the
right value to produce.
INF
is definitely better than FALSE
:)
However there should be a compile-time solution. Maybe, if a division by
zero happens, don't evaluate the expression at compile-time?
Yes. This should be possible.
Keeping WARNING, returning INF
and preventing compile-time evaluation is a
consistent solution for me.
May be you'll also suggest something regarding bitwise shifts with negative
offset?
Allowing negative offsets using opposite directions would fix
inconsistency, but I remember, you didn't like it.
May be keep WARNING (Bit shift by negative number) and then perform shift
in another direction?
- disable negative shifts at compile-time.
Thanks. Dmitry.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi,
May be you'll also suggest something regarding bitwise shifts with negative offset?
Allowing negative offsets using opposite directions would fix inconsistency, but I remember, you didn't like it.
May be keep WARNING (Bit shift by negative number) and then perform shift in another direction?
- disable negative shifts at compile-time.
I don’t think opposite-direction shifts would work well for a few reasons. I don’t believe this is normal behaviour in other languages, for one. Another issue is that << and >> are not actually opposites, they have different behaviour with respect to signs, so there’d be ambiguity as to what $x << -$y means (is it the same as $x >> $y, or does it deal differently with signs?). Negative shifts being used are usually the result of mistakes, as well, so you want to inform the user.
The main problem, though, is that we previously did something different if the shift is negative. Having it now produce a warning, means you’ll see error messages when you run existing code. But shifting in the opposite direction might change the behaviour of existing code silently
I think the most sensible solution would be to make negative shifts produce an exception, since they’re really an error, an unsupported operation. I made them be a warning + return FALSE
just because it matched division. But that’s not ideal and I’d be fine if it was replaced.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi,
May be you'll also suggest something regarding bitwise shifts with
negative offset?
Allowing negative offsets using opposite directions would fix
inconsistency, but I remember, you didn't like it.
May be keep WARNING (Bit shift by negative number) and then perform
shift in another direction?
- disable negative shifts at compile-time.
I don’t think opposite-direction shifts would work well for a few reasons.
I don’t believe this is normal behaviour in other languages, for one.
Another issue is that << and >> are not actually opposites, they have
different behaviour with respect to signs, so there’d be ambiguity as to
what $x << -$y means (is it the same as $x >> $y, or does it deal
differently with signs?). Negative shifts being used are usually the result
of mistakes, as well, so you want to inform the user.The main problem, though, is that we previously did something different if
the shift is negative. Having it now produce a warning, means you’ll see
error messages when you run existing code. But shifting in the opposite
direction might change the behaviour of existing code silentlyI think the most sensible solution would be to make negative shifts
produce an exception, since they’re really an error, an unsupported
operation. I made them be a warning + returnFALSE
just because it matched
division. But that’s not ideal and I’d be fine if it was replaced.
OK. Exception is fine.
So the summary:
-
division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
evaluation is disabled. -
Negative shift produces Exception.Compile-time evaluation is disabled.
-
Modulo by zero produces Exception.Compile-time evaluation is disabled.
Everything right?
I'm going to implement this on Monday.
Thanks. Dmitry.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi,
May be you'll also suggest something regarding bitwise shifts with
negative offset?
Allowing negative offsets using opposite directions would fix
inconsistency, but I remember, you didn't like it.
May be keep WARNING (Bit shift by negative number) and then perform
shift in another direction?
- disable negative shifts at compile-time.
I don’t think opposite-direction shifts would work well for a few
reasons. I don’t believe this is normal behaviour in other languages, for
one. Another issue is that << and >> are not actually opposites, they have
different behaviour with respect to signs, so there’d be ambiguity as to
what $x << -$y means (is it the same as $x >> $y, or does it deal
differently with signs?). Negative shifts being used are usually the result
of mistakes, as well, so you want to inform the user.The main problem, though, is that we previously did something different
if the shift is negative. Having it now produce a warning, means you’ll see
error messages when you run existing code. But shifting in the opposite
direction might change the behaviour of existing code silentlyI think the most sensible solution would be to make negative shifts
produce an exception, since they’re really an error, an unsupported
operation. I made them be a warning + returnFALSE
just because it matched
division. But that’s not ideal and I’d be fine if it was replaced.OK. Exception is fine.
So the summary:
division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
evaluation is disabled.Negative shift produces Exception.Compile-time evaluation is disabled.
Modulo by zero produces Exception.Compile-time evaluation is disabled.
Everything right?
Don't think we need to disable compile-time evaluation for 2) and 3). It'll
just end up being a compile error in that case. I think if you have 1 % 0
occurring in your code literally, it's better to have the compile fail
rather than getting (or not getting) a runtime exception.
Nikita
Hi,
May be you'll also suggest something regarding bitwise shifts with
negative offset?
Allowing negative offsets using opposite directions would fix
inconsistency, but I remember, you didn't like it.
May be keep WARNING (Bit shift by negative number) and then perform
shift in another direction?
- disable negative shifts at compile-time.
I don’t think opposite-direction shifts would work well for a few
reasons. I don’t believe this is normal behaviour in other languages, for
one. Another issue is that << and >> are not actually opposites, they have
different behaviour with respect to signs, so there’d be ambiguity as to
what $x << -$y means (is it the same as $x >> $y, or does it deal
differently with signs?). Negative shifts being used are usually the result
of mistakes, as well, so you want to inform the user.The main problem, though, is that we previously did something different
if the shift is negative. Having it now produce a warning, means you’ll see
error messages when you run existing code. But shifting in the opposite
direction might change the behaviour of existing code silentlyI think the most sensible solution would be to make negative shifts
produce an exception, since they’re really an error, an unsupported
operation. I made them be a warning + returnFALSE
just because it matched
division. But that’s not ideal and I’d be fine if it was replaced.OK. Exception is fine.
So the summary:
division by zero produces a warning and +/-INF IS_DOUBLE.
Compile-time evaluation is disabled.Negative shift produces Exception.Compile-time evaluation is disabled.
Modulo by zero produces Exception.Compile-time evaluation is disabled.
Everything right?
Don't think we need to disable compile-time evaluation for 2) and 3).
It'll just end up being a compile error in that case. I think if you have 1
% 0 occurring in your code literally, it's better to have the compile fail
rather than getting (or not getting) a runtime exception.
This is even easier.
Andrea, what do you think?
Thanks. Dmitry.
Nikita
Don't think we need to disable compile-time evaluation for 2) and 3). It'll just end up being a compile error in that case. I think if you have 1 % 0 occurring in your code literally, it's better to have the compile fail rather than getting (or not getting) a runtime exception.
This is even easier.
Andrea, what do you think?
I was wondering if that might cause problems if you have a large codebase and some unfixed errors in a few places. If the code isn’t being run, only compiled, then it’d be unnecessary pain. However, the chances of a codebase having numerous undetected divisions by zero, that are obvious at compile-time, aren’t very high. So, failing at compile-time is fine.
And, to save another email, I agree with the four items in your summary. Exceptions for negative shift, modulo/intdiv by zero, normal division by zero is +/-INF. :)
--
Andrea Faulds
http://ajf.me/
Am 04.04.2015 um 00:13 schrieb Andrea Faulds:
Don't think we need to disable compile-time evaluation for 2) and 3). It'll just end up being a compile error in that case. I think if you have 1 % 0 occurring in your code literally, it's better to have the compile fail rather than getting (or not getting) a runtime exception.
This is even easier.
Andrea, what do you think?
I was wondering if that might cause problems if you have a large codebase and some unfixed errors in a few places. If the code isn’t being run, only compiled, then it’d be unnecessary pain. However, the chances of a codebase having numerous undetected divisions by zero, that are obvious at compile-time, aren’t very high. So, failing at compile-time is fine.And, to save another email, I agree with the four items in your summary. Exceptions for negative shift, modulo/intdiv by zero, normal division by zero is +/-INF. :)
If the normal division by zero produces +/-INF
it's a valid calculation
and shouldn't trigger a warning else it should end up in an exception, too.
--
Andrea Faulds
http://ajf.me/
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 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 dmitry@zend.com:
So the summary:
division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
evaluation is disabled.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.
Bob
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 dmitry@zend.com:
So the summary:
division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
evaluation is disabled.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
orNAN
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.Bob
I agree with Bob here: It would be nice if the behavior of division and
modulus lined up.
I'd like to add that the choice of returning Inf and additionally throwing
a warning is particularly weird. While using Inf as the result of division
by zero makes sense in some contexts (mainly scientific computing), in
these contexts it's also a perfectly normal operation that would not
generate a warning. If we want to use Inf we should remove the warning as
well. However it should be noted that PHP is not well known for it's
application in scientific computing and for our purposes the exception is
likely more useful.
Nikita
Hi Bob,
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 dmitry@zend.com:
So the summary:
division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
evaluation is disabled.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
orNAN
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/
Hey Andrea,
Am 29.06.2015 um 18:49 schrieb Andrea Faulds ajf@ajf.me:
Hi Bob,
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 dmitry@zend.com:
So the summary:
division by zero produces a warning and +/-INF IS_DOUBLE. Compile-time
evaluation is disabled.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
orNAN
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 produceFALSE
here, which is a different type (boolean). I don’t think that was a good idea because of PHP’s weak typing. If you useFALSE
in some other arithmetic operation, it’ll be coerced to zero, and produce weird results from other operations. Sure, there’s anE_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/ http://ajf.me/
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined behavior, or we throw an exception. Well-defined behavior plus a warning is IMO non-sense.
- Is it intentional for intdiv and % to throw an Exception instead of Error or some more specific DivisionByZeroError or similar? (yes, I know, Error is only very recent, but the question still needs to be asked).
Bob.
Hi again,
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined behavior, or we throw an exception. Well-defined behavior plus a warning is IMO non-sense.
That’s weird, yeah. We don’t throw warnings for the math functions when you give them odd inputs, e.g. sin(INF) is just NAN, no warning.
I think removing it would make sense.
- Is it intentional for intdiv and % to throw an Exception instead of Error or some more specific DivisionByZeroError or similar? (yes, I know, Error is only very recent, but the question still needs to be asked).
Hmm. Using Error might make some sense given it used to raise E_WARNING. I think DivisionByZeroError sounds like a good idea.
--
Andrea Faulds
http://ajf.me/
I, personally, don't have strong opinion. Both behaviors work for me.
Bob, if you are going to change this, please show the patch first.
Thanks. Dmitry.
Hi again,
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined
behavior, or we throw an exception. Well-defined behavior plus a warning
is IMO non-sense.That’s weird, yeah. We don’t throw warnings for the math functions when
you give them odd inputs, e.g. sin(INF) is just NAN, no warning.I think removing it would make sense.
- Is it intentional for intdiv and % to throw an Exception instead of
Error or some more specific DivisionByZeroError or similar? (yes, I know,
Error is only very recent, but the question still needs to be asked).Hmm. Using Error might make some sense given it used to raise E_WARNING. I
think DivisionByZeroError sounds like a good idea.--
Andrea Faulds
http://ajf.me/
Am 29.06.2015 um 19:14 schrieb Andrea Faulds ajf@ajf.me:
Hi again,
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined behavior, or we throw an exception. Well-defined behavior plus a warning is IMO non-sense.
That’s weird, yeah. We don’t throw warnings for the math functions when you give them odd inputs, e.g. sin(INF) is just NAN, no warning.
I think removing it would make sense.
- Is it intentional for intdiv and % to throw an Exception instead of Error or some more specific DivisionByZeroError or similar? (yes, I know, Error is only very recent, but the question still needs to be asked).
Hmm. Using Error might make some sense given it used to raise E_WARNING. I think DivisionByZeroError sounds like a good idea.
Hey,
I just committed that to master…
But I noticed that intdiv(PHP_INT_MIN, -1) isn't very well suited for a DivisionByZeroError.
What do you think about adding an ArithmeticError for that case (and making DivisionByZeroError subclass of it)?
That ArithmeticError could then be reused for negative bitshifts, which would solve the question what to do with that too.
Thanks,
Bob
Hi Bob,
Am 29.06.2015 um 19:14 schrieb Andrea Faulds ajf@ajf.me:
Hmm. Using Error might make some sense given it used to raise E_WARNING. I think DivisionByZeroError sounds like a good idea.
Hey,
I just committed that to master…
Great!
But I noticed that intdiv(PHP_INT_MIN, -1) isn't very well suited for a DivisionByZeroError.
What do you think about adding an ArithmeticError for that case (and making DivisionByZeroError subclass of it)?
That ArithmeticError could then be reused for negative bitshifts, which would solve the question what to do with that too.
Well, that specific case is integer overflow. Normally in PHP we just upgrade to float instead of throwing an error in these situations, but for intdiv()
I didn’t think that made sense (it’s integer division). So, maybe OverflowError would be a better name. But we don’t really do overflow errors anywhere else that I can think of, so the more general ArithmeticError might be fine.
Thanks.
Andrea Faulds
http://ajf.me/
Am 29.06.2015 um 19:14 schrieb Andrea Faulds ajf@ajf.me:
Hi again,
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined
behavior, or we throw an exception. Well-defined behavior plus a warning
is IMO non-sense.That’s weird, yeah. We don’t throw warnings for the math functions when
you give them odd inputs, e.g. sin(INF) is just NAN, no warning.I think removing it would make sense.
- Is it intentional for intdiv and % to throw an Exception instead of
Error or some more specific DivisionByZeroError or similar? (yes, I know,
Error is only very recent, but the question still needs to be asked).Hmm. Using Error might make some sense given it used to raise E_WARNING.
I think DivisionByZeroError sounds like a good idea.Hey,
I just committed that to master…
But I noticed that intdiv(PHP_INT_MIN, -1) isn't very well suited for a
DivisionByZeroError.What do you think about adding an ArithmeticError for that case (and
making DivisionByZeroError subclass of it)?
That ArithmeticError could then be reused for negative bitshifts, which
would solve the question what to do with that too.
I think we should introduce ArithmeticError, as you propose.
Thanks. Dmitry.
Thanks,
Bob
+1 for everything proposed here :-)
Kubo2
2015-07-02 9:59 GMT+02:00 Dmitry Stogov dmitry@zend.com:
Am 29.06.2015 um 19:14 schrieb Andrea Faulds ajf@ajf.me:
Hi again,
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined
behavior, or we throw an exception. Well-defined behavior plus a warning
is IMO non-sense.That’s weird, yeah. We don’t throw warnings for the math functions when
you give them odd inputs, e.g. sin(INF) is just NAN, no warning.I think removing it would make sense.
- Is it intentional for intdiv and % to throw an Exception instead of
Error or some more specific DivisionByZeroError or similar? (yes, I know,
Error is only very recent, but the question still needs to be asked).Hmm. Using Error might make some sense given it used to raise E_WARNING.
I think DivisionByZeroError sounds like a good idea.Hey,
I just committed that to master…
But I noticed that intdiv(PHP_INT_MIN, -1) isn't very well suited for a
DivisionByZeroError.What do you think about adding an ArithmeticError for that case (and
making DivisionByZeroError subclass of it)?
That ArithmeticError could then be reused for negative bitshifts, which
would solve the question what to do with that too.I think we should introduce ArithmeticError, as you propose.
Thanks. Dmitry.
Thanks,
Bob
Hey guys,
I'm proposing that we reconsider removing the warning from floating point
division and here's why.
While IEEE 754 defines special values for floating point arithmetic when
division by zero occurs, there's nothing stopping the language from
providing useful error information to the user, which may help them debug
potentially buggy code. It's true that it's not exceptional since there is
now well defined behavior in the case of changing division by zero to IEEE
754 standard in PHP. However, PHP didn't actually distinguish between
integer division and floating point division prior to intdiv. So in the
case of division by zero the warning was useful to help someone catch their
mistake.
Now, the onus is on the person writing the code to decipher whether or not
they created a potential division by zero scenario by deducing how they
arrived at INF
at some point in their code. This is creating an unnecessary
burden when we've always provided the user with the useful error
information in the past. I'm not sure why we should remove it now, but
based on this conversation I can see that the confusion resonates around
this urge to convert the warning to an exception and the conflict of it not
being exceptional (in the case of floating point math) since there is now
well defined behavior.
So my conclusion is that...
Yes, it's not exceptional. No, we shouldn't throw an exception for division
by zero in floating point arithmetic. No, we shouldn't remove the warning
since it still provides useful information to the person debugging the
code. Debugging the code without this warning can be a monstrosity since
you won't necessarily know at which point in a compounded operation the
division by zero occurred. For example, PHP_INT_MAX
** PHP_INT_MAX
creates
an overflow resulting in INF. Though 0 / INF
results in 0. So an operation
like (1 / ($x / PHP_INT_MAX
** PHP_INT_MAX) where $x happened to be 0 in
one particular case, makes both hunting down and reproducing the bug quite
difficult without some direction. The warning has historically provided
this direction in the past and I believe that removing it now will only
further the confusion.
I don't think people actually care about whether or not we keep the
warning. I think what they would care about more is the consistency of the
return value and defined behavior, which I believe we have already
addressed very well.
+1 for everything proposed here :-)
Kubo2
2015-07-02 9:59 GMT+02:00 Dmitry Stogov dmitry@zend.com:
Am 29.06.2015 um 19:14 schrieb Andrea Faulds ajf@ajf.me:
Hi again,
Yes, it generally makes sense...
Then I have other questions:
- Why do we then still have a Warning? Either we have well-defined
behavior, or we throw an exception. Well-defined behavior plus a
warning
is IMO non-sense.That’s weird, yeah. We don’t throw warnings for the math functions
when
you give them odd inputs, e.g. sin(INF) is just NAN, no warning.I think removing it would make sense.
- Is it intentional for intdiv and % to throw an Exception instead of
Error or some more specific DivisionByZeroError or similar? (yes, I
know,
Error is only very recent, but the question still needs to be asked).Hmm. Using Error might make some sense given it used to raise
E_WARNING.
I think DivisionByZeroError sounds like a good idea.Hey,
I just committed that to master…
But I noticed that intdiv(PHP_INT_MIN, -1) isn't very well suited for a
DivisionByZeroError.What do you think about adding an ArithmeticError for that case (and
making DivisionByZeroError subclass of it)?
That ArithmeticError could then be reused for negative bitshifts, which
would solve the question what to do with that too.I think we should introduce ArithmeticError, as you propose.
Thanks. Dmitry.
Thanks,
Bob
2015-07-04 22:56 GMT+02:00 Sherif Ramadan theanomaly.is@gmail.com:
Hey guys,
I'm proposing that we reconsider removing the warning from floating point
division and here's why.While IEEE 754 defines special values for floating point arithmetic when
division by zero occurs, there's nothing stopping the language from
providing useful error information to the user, which may help them debug
potentially buggy code. It's true that it's not exceptional since there is
now well defined behavior in the case of changing division by zero to IEEE
754 standard in PHP. However, PHP didn't actually distinguish between
integer division and floating point division prior to intdiv. So in the
case of division by zero the warning was useful to help someone catch their
mistake.Now, the onus is on the person writing the code to decipher whether or not
they created a potential division by zero scenario by deducing how they
arrived atINF
at some point in their code. This is creating an unnecessary
burden when we've always provided the user with the useful error
information in the past. I'm not sure why we should remove it now, but
based on this conversation I can see that the confusion resonates around
this urge to convert the warning to an exception and the conflict of it not
being exceptional (in the case of floating point math) since there is now
well defined behavior.So my conclusion is that...
Yes, it's not exceptional. No, we shouldn't throw an exception for division
by zero in floating point arithmetic. No, we shouldn't remove the warning
since it still provides useful information to the person debugging the
code. Debugging the code without this warning can be a monstrosity since
you won't necessarily know at which point in a compounded operation the
division by zero occurred. For example,PHP_INT_MAX
**PHP_INT_MAX
creates
an overflow resulting in INF. Though 0 /INF
results in 0. So an operation
like (1 / ($x /PHP_INT_MAX
** PHP_INT_MAX) where $x happened to be 0 in
one particular case, makes both hunting down and reproducing the bug quite
difficult without some direction. The warning has historically provided
this direction in the past and I believe that removing it now will only
further the confusion.I don't think people actually care about whether or not we keep the
warning. I think what they would care about more is the consistency of the
return value and defined behavior, which I believe we have already
addressed very well.
+1, I fully agree. It's not exceptional, but it's potentially buggy code
and should
therefore produce a warning instead of just returning INF.
I assume, most developers don't want to deal with INF
in their code. If
there's
a warning, they can convert it to an exception which would not be possible
without it.
Regards, Niklas
Am 4.7.2015 um 23:09 schrieb Niklas Keller me@kelunik.com:
2015-07-04 22:56 GMT+02:00 Sherif Ramadan <theanomaly.is@gmail.com mailto:theanomaly.is@gmail.com>:
Hey guys,I'm proposing that we reconsider removing the warning from floating point
division and here's why.While IEEE 754 defines special values for floating point arithmetic when
division by zero occurs, there's nothing stopping the language from
providing useful error information to the user, which may help them debug
potentially buggy code. It's true that it's not exceptional since there is
now well defined behavior in the case of changing division by zero to IEEE
754 standard in PHP. However, PHP didn't actually distinguish between
integer division and floating point division prior to intdiv. So in the
case of division by zero the warning was useful to help someone catch their
mistake.Now, the onus is on the person writing the code to decipher whether or not
they created a potential division by zero scenario by deducing how they
arrived atINF
at some point in their code. This is creating an unnecessary
burden when we've always provided the user with the useful error
information in the past. I'm not sure why we should remove it now, but
based on this conversation I can see that the confusion resonates around
this urge to convert the warning to an exception and the conflict of it not
being exceptional (in the case of floating point math) since there is now
well defined behavior.So my conclusion is that...
Yes, it's not exceptional. No, we shouldn't throw an exception for division
by zero in floating point arithmetic. No, we shouldn't remove the warning
since it still provides useful information to the person debugging the
code. Debugging the code without this warning can be a monstrosity since
you won't necessarily know at which point in a compounded operation the
division by zero occurred. For example,PHP_INT_MAX
**PHP_INT_MAX
creates
an overflow resulting in INF. Though 0 /INF
results in 0. So an operation
like (1 / ($x /PHP_INT_MAX
** PHP_INT_MAX) where $x happened to be 0 in
one particular case, makes both hunting down and reproducing the bug quite
difficult without some direction. The warning has historically provided
this direction in the past and I believe that removing it now will only
further the confusion.I don't think people actually care about whether or not we keep the
warning. I think what they would care about more is the consistency of the
return value and defined behavior, which I believe we have already
addressed very well.+1, I fully agree. It's not exceptional, but it's potentially buggy code and should
therefore produce a warning instead of just returning INF.I assume, most developers don't want to deal with
INF
in their code. If there's
a warning, they can convert it to an exception which would not be possible
without it.Regards, Niklas
Generally, that was my first proposal, and I’d still support it and would like to implement it, when other people are agreeing here.
As Andrea objected to that ( / floating point division should be handled like IEEE 754…), I’d like to wait for further opinions on this before committing anything in this direction.
Ideally, I’d prefer to have that solved until Monday evening so that I can change it before beta 1 tagging.
Thanks,
Bob
Hey Sherif,
I'm proposing that we reconsider removing the warning from floating point division and here's why.
While IEEE 754 defines special values for floating point arithmetic when division by zero occurs, there's nothing stopping the language from providing useful error information to the user, which may help them debug potentially buggy code. It's true that it's not exceptional since there is now well defined behavior in the case of changing division by zero to IEEE 754 standard in PHP. However, PHP didn't actually distinguish between integer division and floating point division prior to intdiv. So in the case of division by zero the warning was useful to help someone catch their mistake.
Now, the onus is on the person writing the code to decipher whether or not they created a potential division by zero scenario by deducing how they arrived at
INF
at some point in their code. This is creating an unnecessary burden when we've always provided the user with the useful error information in the past. I'm not sure why we should remove it now, but based on this conversation I can see that the confusion resonates around this urge to convert the warning to an exception and the conflict of it not being exceptional (in the case of floating point math) since there is now well defined behavior.So my conclusion is that...
Yes, it's not exceptional. No, we shouldn't throw an exception for division by zero in floating point arithmetic. No, we shouldn't remove the warning since it still provides useful information to the person debugging the code. Debugging the code without this warning can be a monstrosity since you won't necessarily know at which point in a compounded operation the division by zero occurred. For example,
PHP_INT_MAX
**PHP_INT_MAX
creates an overflow resulting in INF. Though 0 /INF
results in 0. So an operation like (1 / ($x /PHP_INT_MAX
** PHP_INT_MAX) where $x happened to be 0 in one particular case, makes both hunting down and reproducing the bug quite difficult without some direction. The warning has historically provided this direction in the past and I believe that removing it now will only further the confusion.I don't think people actually care about whether or not we keep the warning. I think what they would care about more is the consistency of the return value and defined behavior, which I believe we have already addressed very well.
Yeah, keeping it around makes sense.
Thing is, if it’s a problem, you can silence it with @, so @($a / $b). If that’s slow, we could optimise it (make it call div_function_no_error or something?)
Thanks.
Andrea Faulds
http://ajf.me/
Am 05.07.2015 um 00:50 schrieb Andrea Faulds ajf@ajf.me:
Hey Sherif,
I'm proposing that we reconsider removing the warning from floating point division and here's why.
While IEEE 754 defines special values for floating point arithmetic when division by zero occurs, there's nothing stopping the language from providing useful error information to the user, which may help them debug potentially buggy code. It's true that it's not exceptional since there is now well defined behavior in the case of changing division by zero to IEEE 754 standard in PHP. However, PHP didn't actually distinguish between integer division and floating point division prior to intdiv. So in the case of division by zero the warning was useful to help someone catch their mistake.
Now, the onus is on the person writing the code to decipher whether or not they created a potential division by zero scenario by deducing how they arrived at
INF
at some point in their code. This is creating an unnecessary burden when we've always provided the user with the useful error information in the past. I'm not sure why we should remove it now, but based on this conversation I can see that the confusion resonates around this urge to convert the warning to an exception and the conflict of it not being exceptional (in the case of floating point math) since there is now well defined behavior.So my conclusion is that...
Yes, it's not exceptional. No, we shouldn't throw an exception for division by zero in floating point arithmetic. No, we shouldn't remove the warning since it still provides useful information to the person debugging the code. Debugging the code without this warning can be a monstrosity since you won't necessarily know at which point in a compounded operation the division by zero occurred. For example,
PHP_INT_MAX
**PHP_INT_MAX
creates an overflow resulting in INF. Though 0 /INF
results in 0. So an operation like (1 / ($x /PHP_INT_MAX
** PHP_INT_MAX) where $x happened to be 0 in one particular case, makes both hunting down and reproducing the bug quite difficult without some direction. The warning has historically provided this direction in the past and I believe that removing it now will only further the confusion.I don't think people actually care about whether or not we keep the warning. I think what they would care about more is the consistency of the return value and defined behavior, which I believe we have already addressed very well.
Yeah, keeping it around makes sense.
Thing is, if it’s a problem, you can silence it with @, so @($a / $b). If that’s slow, we could optimise it (make it call div_function_no_error or something?)
At that point it's just a bit weird. The @ operator IMO shouldn't be the recommended way to handle fundamental operations.
You ideally just check if the divisor is 0 and then do the operation.
And at that point, we should just throw the DivisionByZeroError.
Honestly, a warning is just the wrong thing to use. Either you enable it (like double division in C) or disable it completely (runtime exception in C).
I can get behind both, but not behind a warning.
Thanks,
Bob.
You ideally just check if the divisor is 0 and then do the operation.
And at that point, we should just throw the DivisionByZeroError.Honestly, a warning is just the wrong thing to use. Either you enable it (like double division in C) or disable it completely (runtime exception in C).
I can get behind both, but not behind a warning.
+1
Am 05.07.2015 um 00:50 schrieb Andrea Faulds ajf@ajf.me:
Hey Sherif,
I'm proposing that we reconsider removing the warning from floating point division and here's why.
While IEEE 754 defines special values for floating point arithmetic when division by zero occurs, there's nothing stopping the language from providing useful error information to the user, which may help them debug potentially buggy code. It's true that it's not exceptional since there is now well defined behavior in the case of changing division by zero to IEEE 754 standard in PHP. However, PHP didn't actually distinguish between integer division and floating point division prior to intdiv. So in the case of division by zero the warning was useful to help someone catch their mistake.
Now, the onus is on the person writing the code to decipher whether or not they created a potential division by zero scenario by deducing how they arrived at
INF
at some point in their code. This is creating an unnecessary burden when we've always provided the user with the useful error information in the past. I'm not sure why we should remove it now, but based on this conversation I can see that the confusion resonates around this urge to convert the warning to an exception and the conflict of it not being exceptional (in the case of floating point math) since there is now well defined behavior.So my conclusion is that...
Yes, it's not exceptional. No, we shouldn't throw an exception for division by zero in floating point arithmetic. No, we shouldn't remove the warning since it still provides useful information to the person debugging the code. Debugging the code without this warning can be a monstrosity since you won't necessarily know at which point in a compounded operation the division by zero occurred. For example,
PHP_INT_MAX
**PHP_INT_MAX
creates an overflow resulting in INF. Though 0 /INF
results in 0. So an operation like (1 / ($x /PHP_INT_MAX
** PHP_INT_MAX) where $x happened to be 0 in one particular case, makes both hunting down and reproducing the bug quite difficult without some direction. The warning has historically provided this direction in the past and I believe that removing it now will only further the confusion.I don't think people actually care about whether or not we keep the warning. I think what they would care about more is the consistency of the return value and defined behavior, which I believe we have already addressed very well.
Yeah, keeping it around makes sense.
Thing is, if it’s a problem, you can silence it with @, so @($a / $b). If that’s slow, we could optimise it (make it call div_function_no_error or something?)
At that point it's just a bit weird. The @ operator IMO shouldn't be the recommended way to handle fundamental operations.
You ideally just check if the divisor is 0 and then do the operation.
And at that point, we should just throw the DivisionByZeroError.Honestly, a warning is just the wrong thing to use. Either you enable it (like double division in C) or disable it completely (runtime exception in C).
I can get behind both, but not behind a warning.
Thanks,
Bob.
+1
In my opinion division by zero should result in some notification. I think a DivisionByZeroError seems the most appropriate. If a user wants the result of NaN or Inf it is trivial to write a function for that purpose. Perhaps PHP could provide such a function.
Aaron Piotrowski
- Division by zero behavior in PHP is really inconsistent.
It emits WARNING and returns FALLE.Note, that since PHP-5.6 division by zero may also occur in constant
expressions. They are compiled and evaluated only once (on first request)
and on next request WARNING is going to be hidden.$ cat div.php
<?php
class C {
const T = 5 / 0;
}
var_dump(C::T);
?>$ sapi/cgi/php-cgi -q -T 3 div.php
PHP Warning: Division by zero in
/home/dmitry/php/php-master/CGI-DEBUG/div.php on line 3
bool(false)
bool(false)
bool(false)I propose to change this into fatal error for division by zero at
compile-time and exception a run-time.
- Very similar weird behavior was introduced for shift with negative
offsets. I also propose to change it in the same way (Fatal error at
compile-time, Exception in run-time).Any thoughts? objections?
I'm okay with making both of these exceptions. It's really weird if
dividing two numbers you can suddenly end up with a boolean...
Nikita
- Very similar weird behavior was introduced for shift with negative
offsets. I also propose to change it in the same way (Fatal error at
compile-time, Exception in run-time).
Can you describe the weird behavior for shifts with negative offsets?
- Very similar weird behavior was introduced for shift with negative
offsets. I also propose to change it in the same way (Fatal error at
compile-time, Exception in run-time).Can you describe the weird behavior for shifts with negative offsets?
$ sapi/cli/php -n -r "var_dump(1 << -1);"
Warning: Bit shift by negative number in Command line code on line 1
bool(false)
Currently this expression may also be evaluated at compile-time.
Thanks. Dmitry.
- One more problem is modulo :(
$ sapi/cli/php -n -r "var_dump(1 % 0);"
Warning: Division by zero in Command line code on line 1
bool(false)
Thanks. Dmitry.
- Very similar weird behavior was introduced for shift with negative
offsets. I also propose to change it in the same way (Fatal error at
compile-time, Exception in run-time).Can you describe the weird behavior for shifts with negative offsets?
$ sapi/cli/php -n -r "var_dump(1 << -1);"
Warning: Bit shift by negative number in Command line code on line 1
bool(false)Currently this expression may also be evaluated at compile-time.
Thanks. Dmitry.
Hi,
- One more problem is modulo :(
$ sapi/cli/php -n -r "var_dump(1 % 0);"
Warning: Division by zero in Command line code on line 1
bool(false)
Hmm, modulo is a more difficult one. Since it’s an integer-only operation in PHP, producing INF
doesn’t make sense. It also doesn’t make sense mathematically. I think the most sensible thing to do here would be to throw an exception.
On the same note, the new function intdiv()
is the counterpart to % for obtaining the quotient (% produces the remainder). It currently does the same thing as % and / division and produces FALSE
with a warning. If % is changed, intdiv()
should be too, because they are the same operation, just returning different parts of the result. An exception being produced by both would seem reasonable.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi,
- One more problem is modulo :(
$ sapi/cli/php -n -r "var_dump(1 % 0);"
Warning: Division by zero in Command line code on line 1
bool(false)Hmm, modulo is a more difficult one. Since it’s an integer-only operation
in PHP, producingINF
doesn’t make sense. It also doesn’t make sense
mathematically. I think the most sensible thing to do here would be to
throw an exception.On the same note, the new function
intdiv()
is the counterpart to % for
obtaining the quotient (% produces the remainder). It currently does the
same thing as % and / division and producesFALSE
with a warning. If % is
changed,intdiv()
should be too, because they are the same operation, just
returning different parts of the result. An exception being produced by
both would seem reasonable.
Cool :)
- fix
intdiv()
to throw exception.
Thanks. Dmitry,
Thanks.
--
Andrea Faulds
http://ajf.me/