ID:               34179
 User updated by:  pww8 at cornell dot edu
 Reported By:      pww8 at cornell dot edu
 Status:           Open
 Bug Type:         Feature/Change Request
 Operating System: Linux 2.4.9
 PHP Version:      5.0.4
 New Comment:

Various math operations can correctly generate +Inf or -Inf or NaN (Not
a Number).

Seems to me 3 reasonable things to do with those results:

  1. Issue warning and return default result, as now done on 1.0/0.0;

  2. Raise an exception;

  3. Return the correct result, where possible, as a native float. 
That is, NaN or Inf in 32 or 64 bits, which is possible on all current
machines I know of (a small set).

I would prefer option 3.

Note that PHP now uses option 3 in many operations, including multiply
[operator *], log10(), exp().

I don't agree that "no one divides by 0 or generates overflow on
purpose".  As a contrived example, you may have a set of X-Y points
where Y = f(X), some values of Y are Inf and some are not.  The user
looks at a graph, with infinities marked, and understands.  User then
applies another function Z = ff(Y) and expects the infinities to
participate.  For example:


rad2deg(atan(Inf))  =>  90
 
  which can be seen in PHP by:

rad2deg(atan(exp(1.0e200)));


Furthermore, there are many cases where the user did not intend to
create an Inf, but would still prefer that the Inf's be created and
displayed instead of the whole calculation being tossed.  The example
again could be graphing a lot of X-Y data where a few Inf or NaN will
be understoo dby the user, and the remaining in-range data is useful
and should be displayed.

Actually, 1.0/0.0 should be +Inf, 0.0/0.0 should be NaN.

I guess raising an exception might be better than issuing the warning,
but the amount of extra code I would have to write to generate the Inf
or NaN would be the same as the present implementation.  And, just
adding the exception for divide by zero is inconsistent with the
present * , log10(), exp(), etc...

I also think it's impolite to change existing behavior of divide by
zero.

Ideally I see a programmer-settable choice, maybe at runtime, maybe
only on startup, among 3 options:

 1. present behavior (sometimes warn, sometimes produce Inf or Nan);

 2. raise exception on any out of range result;

 3. generate correct out of range floating point bit pattern on all
out-of-range results, unless the present hardware does not support it
(see standard IEEE 754).

So if the programmer tries to set option 3 at runtime, and present
hardware does not support it, an error should be returned from the
option setter function.

One possible problem with my proposal: if some existing builtin
function [say acosh()] is internally generating Inf's, and sucessfully
using them to generate in-range values, option 2 would have to be
implemented so those internal Inf's did not raise an exception.

My proposal is based on my former job writing a graphing calculator
subsystem for engineers, using Smalltalk.  Not based on a current
project need.  And, from years of discussion with Smalltalk programmers
and vendors, I realize not all programmers know IEEE 754.


Previous Comments:
------------------------------------------------------------------------

[2005-09-04 23:52:36] yaXay at gmx dot net

As far as I know 1/0 is undefined (lim x->0 (1/x) is inf.), as well as
1.0e300*1.0e300 simply produces an overflow. Of course that is just a
technicality, but still..

Regarding devide by zero and overflows, I would go even further and
throw an exception, because that is what they are: exceptions. Nobody
divides by zero or generates overflows on purpose. They usually occur
on erroneous user input. Throwing exceptions would of course force the
programmer to be more aware of this issue, since exceptions have a
habit of stopping execution when they are not caught. Howerver I find
it good to force the programmer to produce clean code, I mean, what is
the downside??

Sincerely,
Benjamin Schulz

------------------------------------------------------------------------

[2005-08-18 00:44:16] pww8 at cornell dot edu

Description:
------------
It appears floating-point infinity (INF) is not returned from divide by
zero (in PHP 5.0.0).  Instead a warning is given and Boolean FALSE is
returned.

This is no doubt well-known behavior to most users, probably would be
confusing to change the default.  But it would be useful for me to
throw a switch or set an .ini file variable to some non-default state,
and get the correct answer instead of FALSE.

Note that you can get INF from multiply, e.g. 1.0e300*1.0e300 [Linux on
Intel].  Might also be nice to get INF when it is the correct answer!

Reproduce code:
---------------
// Expected result would be after I set some non-default
//  floating point handling mode above...

$varxx = 1.0 / 0.0;
$if (isset($varxx))
{  boolean = is_bool($varxx) ? "Boolean" : "Not Boolean" ;
   print "\nSET $varxx $boolean";
}
else
{ print "\nNOT SET"; }
 
print "\nanother test, exp of very large number is : " . exp(1.0e300);
print "\ntry for infinity using * : " . 1.0e300*1.0e300;


Expected result:
----------------
SET INF Not Boolean
another test, exp of very large number is : INF
try for infinity using * : INF


Actual result:
--------------
SET  Boolean
another test, exp of very large number is : INF
try for infinity using * : INF



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=34179&edit=1

Reply via email to