note 110823 added to function.fmod
| From: | verdy_p at wanadoo dot fr | Date: | Wed, 12 Dec 2012 02:23:30 +0000 |
| Subject: | note 110823 added to function.fmod | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-192480@lists.php.net to get a copy of this message | ||
Square root of 0 is perfectly defined. 0 elevated at any non-zero finite power is always 0, even
when you work with complexes.
The ONLY power of 0 whose result is NaN is 0^0 :
0^(1/2) = exp(log(0)*(1/2)) = exp(-INF*(1/2)) = exp(-INF) = 0
0^0 = exp(log(0)*0) = exp(-INF*0) = exp(NaN) = NaN
1^0 = exp(log(1)*0) = exp(0*0) = exp(0) = 1
(-2)^0 is more difficult to define, but it remains valid:
function pow(double a, double b) {
if (b == floor(b)) {
if ((b/2)=floor(b/2)) // b is even
return exp(log(abs(a))*b);
else // b is odd
return exp(log(abs(a))*b)*sng(a);
} else {
// If b is the inverse of an integer, the result has
// multiple solutions, not real but complex.
// We could take an arbitrary complex root such as
// such as the root with the smallest positive imaginary
// part and the largest real part (possibly negative).
// But if the function must return only a real value,
// there's no solution.
// If b any other non-integer value, there's no real or
// complex solution at all:
// Note that only inverses of powers of 2 are exactly
// stored (e.g. b==1.2, but not b==1/3; this limits
// our detection of cubic roots here).
throw FPexception;
}
}
With this function (-2)^0 = pow(-2,0), a==-2 and b==0 is an even integer, so we return:
exp(log(abs(a))*b) = exp(log(abs(-2))*0) = exp(log(2)*0) =exp(0) = 1
The case where this cannot return a value is when a==0 and b==0 (even integer):
exp(log(abs(a))*b) = exp(log(abs(0))*0) = exp(log(0)*0) =exp(-INF*0) = exp(NaN) = NaN
For other cases of a^0, where a != 0, we have:
exp(log(abs(a))*b) = exp(log(abs(a))*0) = exp(FINITE*0) =exp(0) = 1
If a is infinite (positive or negative) and b positive, we have:
exp(log(abs(a))*b) = exp(log(abs(INF))*b) = exp(+INF*+FINITE) =exp(+INF) = +INF
If a is infinite (positive or negative) and b negative, we have:
exp(log(abs(a))*b) = exp(log(abs(INF))*b) = exp(+INF*-FINITE) =exp(-INF) = 0
If a is NaN, we have:
exp(log(abs(a))*b) = exp(log(abs(NaN))*b) = exp(NaN*b) =exp(NaN) = NaN
The pow(a,b) function in PHP should then be defined for negative values of a, and for all finite
integer values of b if a is positive.
In order to define a return value when b is a negative power of 2, this works only up to the
precision of doubles : each ime b is divided by 2 you loose 1 bit of precision in the logarithm of
a, and the result of the multiplication also becomes twice less significant. If doubles cannot store
powers of 2 lower than 2^-1024, then the result of a^b will be NaN if b < 2^-104.
----
Server IP: 69.147.83.199
Probable Submitter: 72.52.91.2 (proxied: 89.2.191.39)
----
Manual Page -- http://php.net/manual/en/function.fmod.php
Edit -- https://master.php.net/note/edit/110823
Del: integrated -- https://master.php.net/note/delete/110823/integrated
Del: useless -- https://master.php.net/note/delete/110823/useless
Del: bad code -- https://master.php.net/note/delete/110823/bad+code
Del: spam -- https://master.php.net/note/delete/110823/spam
Del: non-english -- https://master.php.net/note/delete/110823/non-english
Del: in docs -- https://master.php.net/note/delete/110823/in+docs
Del: other reasons-- https://master.php.net/note/delete/110823
Reject -- https://master.php.net/note/reject/110823
Search -- https://master.php.net/manage/user-notes.php