GingerRobot Posted August 27, 2007 Share Posted August 27, 2007 I don't particularly like to ask another question relating to the workings of the maths functions in PHP in the same day, however, ive just noticed something which seems rather odd. It seems to me like PHP cannot calculate a negative number raised to a non-integer power. For example, this code: <?php for($x=-10;$x<=10;$x++){ echo $x.'=>'.pow($x,(2/3)).'<br />'; } ?> Produces: -10=>-1.#IND -9=>-1.#IND -8=>-1.#IND -7=>-1.#IND -6=>-1.#IND -5=>-1.#IND -4=>-1.#IND -3=>-1.#IND -2=>-1.#IND -1=>-1.#IND 0=>0 1=>1 2=>1.58740105197 3=>2.08008382305 4=>2.51984209979 5=>2.92401773821 6=>3.30192724889 7=>3.65930571002 8=>4 9=>4.32674871092 10=>4.64158883361 Using pow($x,1.5) or anything similar produces results like those above. Any thoughts? Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 27, 2007 Share Posted August 27, 2007 I've never seen the #IND warning before, the pow function has a 3 tier system trying to return an integer if possible, if not a float then a false if the answer can not be done, but the #IND is a mystery here Quote Link to comment Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 I'm guessing it's to do with roots of negative numbers being imaginary numbers and not real. Quote Link to comment Share on other sites More sharing options...
GingerRobot Posted August 27, 2007 Author Share Posted August 27, 2007 I think you're pretty much there Barand. Was just doing a bit of investigating with my calculator. However, it does seem that you do not always end up with complex numbers. For example, (-1)^2.1 is non-real, whilse (-1)^2.2 equals -1. I've no idea why that happens, im just off to google. Might have to ask my maths teacher when im back at 6th form. Ill save it for a particularly boring lesson when a change of subject is much needed. Quote Link to comment Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 I would have expected all powers >= 1 to be OK. The problems should be with things like pow (-1, 0.5) ie sqrt(-1) Quote Link to comment Share on other sites More sharing options...
GingerRobot Posted August 27, 2007 Author Share Posted August 27, 2007 Im now confusing myself the more i think about it. I was looking at this example: (-4)^(3/2) now, 4^(3/2) is 8. Since you do (4^3)^(1/2) = 64^(1/2) = 8. Following the same pattern, you get ((-4)^3)^(1/2) = (-64)^1/2. So you get non-real anwer (8i if you're interested). So far, that makes sense. However, isn't 6/4 the same as 3/2? Couldn't you therefore do (-4)^(6/4)? (-4)^(6/4) = ((-4)^6)^(1/4) = 4096^(1/4) = 8. How can it be that by changing the power to an equal fraction, you can solve with a real answer? Perhaps there is a huge flaw in my maths somewhere. Quote Link to comment Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 Raising a neg number to an even power gives a positive number Quote Link to comment Share on other sites More sharing options...
GingerRobot Posted August 27, 2007 Author Share Posted August 27, 2007 Indeed. It just seems very odd to me that by choosing a different but equal fraction, you can find a real solution to the question. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 27, 2007 Share Posted August 27, 2007 Alright what i've concluded is we need to be able to solve this answer in a 2 tiered section using the idea that i^2 = -1 or sqrt(-1) = i. The problem I am seeing is that we can't get it to return a value that is complex (which is the whole goal of a new function). What I've thought about is rewriting the base as (-1($base))^pow but that doesn't exactly get you very far. However I can up with a secondary part that might be helpful. The answer to 9^2.5 is 243 which can be expressed as (9)(9)(9)^.5 so what my idea is based on what ever N is we can solve saying [code] <?php $power = explode(".",$pow); $whole = $power[0]; $dec = $power[1]; $part = 1; for($x= 1; $x <=$whole; $x++){ $part = $part*$int; } ?> This will get us the result of the integer value * the integer portion of the power which is going to be very close to the real answer (varying by int^deci power * Approx). Now we have part of an answer in a semi useful method which is <?php $answer = $part*(($int)^$dec) ?> which might sound complex, but now all we need to do is simply solve something to a power <1 but greater than 0 (or less than 0 but greater than -1) Which we know will be complex answer in the form of z= x +yi which is all we need to do. I'll think about it and come up for a solution and all we need to do is simply multiply the 2 parts and we have a solution.[/code] Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 27, 2007 Share Posted August 27, 2007 I can edit it anymore so i took it out of code for you all: Alright what i've concluded is we need to be able to solve this answer in a 2 tiered section using the idea that i^2 = -1 or sqrt(-1) = i. The problem I am seeing is that we can't get it to return a value that is complex (which is the whole goal of a new function). What I've thought about is rewriting the base as (-1($base))^pow but that doesn't exactly get you very far. However I can up with a secondary part that might be helpful. The answer to 9^2.5 is 243 which can be expressed as (9)(9)(9)^.5 so what my idea is based on what ever N is we can solve saying [code] <?php $power = explode(".",$pow); $whole = $power[0]; $dec = $power[1]; $part = 1; for($x= 1; $x <=$whole; $x++){ $part = $part*$int; } ?> This will get us the result of the integer value * the integer portion of the power which is going to be very close to the real answer (varying by int^deci power * Approx). Now we have part of an answer in a semi useful method which is <?php $answer = $part*(($int)^$dec) ?> which might sound complex, but now all we need to do is simply solve something to a power <1 but greater than 0 (or less than 0 but greater than -1) Which we know will be complex answer in the form of z= x +yi which is all we need to do. I'll think about it and come up for a solution and all we need to do is simply multiply the 2 parts and we have a solution.[/code] Quote Link to comment Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 <?php $pow = '2.5'; // give it a value to play with $power = explode(".",$pow); $whole = $power[0]; $dec = $power[1]; $part = 1; for($x= 1; $x <=$whole; $x++){ $part = $part*$int; } echo $part; // output result --> always 0 ?> It always produces 0 for $part. Where does $int come from? Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 27, 2007 Share Posted August 27, 2007 $int is the number you are putting to a power ($int^$pow) so define $int Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted August 27, 2007 Share Posted August 27, 2007 $int is the number you are putting to a power ($int^$pow) so define $int You are aware that ^ is a bitwise operator and not an arithmetic operator in PHP, right? It means bitwise xor. That might give unexpected/unintended results. E.g. <?php echo 5^9; ?> outputs 12 and not 1953125 because 5 in binary is 00000101 and 3 in binary is 00001001, then the only bits that are set (but not in both) is the 4 and 8 meaning it'll give 00001100 which is 12 in decimal. Edit: See: http://www.phpfreaks.com/tutorials/151/0.php Quote Link to comment Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 Treat it (x^y) as pseudocode Quote Link to comment Share on other sites More sharing options...
Barand Posted August 27, 2007 Share Posted August 27, 2007 OK. Followed the instructions on the packet <?php $int = 2; $pow = '2.5'; // give it a value to play with $power = explode(".",$pow); $whole = $power[0]; $dec = $power[1]; $part = 1; for($x= 1; $x <=$whole; $x++){ $part = $part*$int; } $answer = $part*pow($int,$dec); echo $answer; // 128 ??? ?> I'd expect 2^2.5 to be somewhere between 4 and 8 Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 27, 2007 Share Posted August 27, 2007 I know the ^ is bitwise I was writing psedo code so in your case $whole should be 2 (check it by echoing it out) and part should be 5 which explains all your problem because you are doing pow($int,$dec) which is 2^5 (psedo code) instead of 2^.5 as i've stated this is where we hit the wall because of the imaginary issue. so it does work right because that is 2^7 which is 128 if i do believe I am right. Quote Link to comment Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 so it does work right so , according to your code 2^2.5 = 2^7 = 128 I guess the problem is that this isn't mathematical modeling of real world applications using partial differential equations and integral calculus, your particular expertise. Quote Link to comment Share on other sites More sharing options...
btherl Posted August 28, 2007 Share Posted August 28, 2007 Perhaps there is a huge flaw in my maths somewhere. Check here Note the use of the word "positive" Also read this (which explains why rational powers of negative reals are troublesome) Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 28, 2007 Share Posted August 28, 2007 barnd read before you attempt to criticize some one. I siad the fact was that the code lacked the proper value for the piecewise evaluation. I never said 2^2.5=2^7 i said because the .5 wasn't being treated as .5 but as 5 it was treating the net sum as 2^7 otherwise the method works perfectly. You are so quick to break down someone else's work when you can't find your own method to it Real all that is left is to evaulate x^$dec which can be done using a sum of a certain series that name is evading me. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 28, 2007 Share Posted August 28, 2007 I've come to the conclusion that the basic math package of php can not handle complex numbers due to the fact that php can apply math to anything outside int,floats (or strings that are considered numerical) Therefore this follow snippette of code I've developed will show NAN always on $part[2] because sqrt(-1) is failing unless you can see some conclusion to why this is happening. However there is the PEAR package for handling complex numbers which will probably have a simple function for this http://pear.php.net/package/Math_Complex <?php //The Goal of this function is to return an answer in the format of z = x +yi function pow_neg($int, $pow){ //If Power is less than 0 it is negative so lets flip this equation upside down and work with it that way. if($pow <0){ $pow = -1*$pow; $int = 1/$int; } //Dealing with the seperation of the values $power = explode(".",$pow); $whole = $power[0]; //Don't want to lose that negative on the decimal part if($pow<0){ $dec = -1*$power[1]; } else{ $dec = $power[1]; } //Initialization of the value for parts (if its 0 than the equation will not work) $part = array(); $part[0] = 1; //Cacluation of $int^$whole that will be multiplied by the decimal times x. for($x= 1; $x <=$whole; $x++){ $part[0] = $part[0]*$int; } //Now we must deal with the fractional part if($int <0){ //Lets do this piecewise and deal with the negative using known rules and then the rest $part[1] = pow((-1*$int),$dec); $part[2] = pow(sqrt(-1),$dec*2); } else{ $part[1] = pow($int,$dec); } $i = 0; foreach($part as $value){ echo $i.": ".$value."<br/>"; $i++; } } if(!empty($_GET['int']) && !empty($_GET['pow'])){ $value = pow_neg($_GET['int'], $_GET['pow']); } ?> <form action="calc.php" method="get"> <label>Number</label><input type="text" name="int" /> <label>Power</label><input type="text" name="pow" /> <br/> <input type="submit" value="submit" /> </form> Quote Link to comment Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 barnd read before you attempt to criticize some one. I siad the fact was that the code lacked the proper value for the piecewise evaluation. I never said 2^2.5=2^7 i said because the .5 wasn't being treated as .5 but as 5 it was treating the net sum as 2^7 otherwise the method works perfectly. You are so quick to break down someone else's work when you can't find your own method to it Real all that is left is to evaulate x^$dec which can be done using a sum of a certain series that name is evading me. According to you , it works, when the issue was to find 2^2.5, and the result is 128. So your defininition of "works", then, is that it gives the predicted wrong answer. You're the one posing as the maths expert around here, not me, but all we get is a load mathematical techno-speak and useless code. You are so quick to break down someone else's work Give us some code then, O wise one, that can't be broken down quite so easily. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted August 28, 2007 Share Posted August 28, 2007 You still don't read its all 1st version of code that is very untested you can't accuse the code if you can't read. Quote Link to comment Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 Was that English? Untested - really? Quote Link to comment Share on other sites More sharing options...
GingerRobot Posted August 28, 2007 Author Share Posted August 28, 2007 Perhaps there is a huge flaw in my maths somewhere. Check here Note the use of the word "positive" Also read this (which explains why rational powers of negative reals are troublesome) Hmm, yes i do follow that. I notice that the method shown there is to use the fractional power inside the bracket, and the integer power outside. That would indeed mean that if the denominator were even, you could not find a real solution if the base is negative. However, im fairly sure there is nothing to say that you have to use the fractional power inside the bracket. As far as i know (x^(1/b))^a is identical to (x^b)^(1/a). Definitely one for my maths teacher i think. Quote Link to comment Share on other sites More sharing options...
Barand Posted August 28, 2007 Share Posted August 28, 2007 Can someone verify? <?php if (isset ($_GET['int'])) { $int = $_GET['int']; if (strstr($_GET['pow'], '/')) { list($x,$y) = explode('/', $_GET['pow']); echo powfrac($int, $x, $y); if ($int < 0 && $y > $x) echo 'i'; } else { $pow = 10*round($_GET['pow'],1); // 1 dec place $whole = floor($pow/10); $dec = $pow%10; echo "Calculating $int^$whole * $int^($dec/10)<br>"; echo pow($int, $whole) * powfrac($int, $dec, 10); if ($int < 0 && $pow < 10) echo 'i'; } } function powfrac($n, $num, $den) { $a = $num; $b = $den; do // HCF { $rem=$a%$b; $a=$b; $b=$rem; } while($rem!==0); $num /= $a; $den /= $a; if ($num%2) { $num *= 2; $den *= 2; } echo "Calculating ($n^$num) ^ (1/$den)<br>"; return pow(pow($n, $num), 1/$den); } ?> <form action="" method="get"> <label>Number</label><input type="text" name="int" /> <label>Power</label><input type="text" name="pow" /> (1 dec place or x/y) <br/> <input type="submit" value="submit" /> </form> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.