Go Back   CodingForums.com > :: Server side development > PHP > Post a PHP snippet

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 02-28-2012, 08:32 AM   PM User | #1
djh101
Regular Coder

 
djh101's Avatar
 
Join Date: May 2009
Location: Santa Clarita
Posts: 603
Thanks: 48
Thanked 63 Times in 63 Posts
djh101 is an unknown quantity at this point
caret (^) to pow() function

Having to work with derivatives a lot, I made this nice, simple function for converting a^b form exponents in strings to eval'able pow(a,b) form. Enjoy.

PHP Code:
function carToPow($expression){
    
//array of positions: start of base, position of ^, end of power
    
$pos = array(null,null,null);
    
//array of parts: base and power
    
$parts = array();
    
    for(
$i=0$i<strlen($expression); $i++){
        
        if(
$expression[$i] === '^'){
            
$pos[1] = $i;
            
            
//scan for base
            
if($expression[$i-1] === ')'){ //base is a function
                
$depth 0;
                for(
$j=$i-1$j >= 0$j--){
                    if(
$expression[$j] === ')'$depth++;
                    if(
$expression[$j] === '('$depth--;
                    if(
$depth == 0){
                        
$pos[0] = $j;
                        
$parts[0] = substr($expression$j$i-$j);
                        break;
                    }
                }
            } else if(
$expression[$i-1] === 'x'){ //base is a variable
                
$pos[0] = $i-1;
                
$parts[0] = "x";
            } else { 
//base is a number
                
if(preg_match("/\\d*\\.{0,1}\\d+\\^/",$expression,$foo)){
                    
$pos[0] = $i strlen($foo[0]) + 1;
                    
$parts[0] = substr($foo[0],0,strlen($foo[0])-1);
                } else return 
false;
            }
            
            
//scan for power
            
if($expression[$i+1] === '('){ //power is a function
                
$depth 0;
                for(
$j=$i+1$j strlen($expression); $j++){
                    if(
$expression[$j] === '('$depth++;
                    if(
$expression[$j] === ')'$depth--;
                    if(
$depth == 0){
                        
$pos[2] = $j;
                        
$parts[1] = substr($expression$i+1$j-$i);
                        break;
                    }
                }
            } else if(
$expression[$i+1] === 'x'){ //base is a variable
                
$pos[2] = $i+1;
                
$parts[1] = "x";
            } else { 
//power is a number
                
if(preg_match("/\\^\\d*\\.{0,1}\\d+/",$expression,$foo)){
                    
$pos[2] = $i strlen($foo[0]) - 1;
                    
$parts[1] = substr($foo[0],1,strlen($foo[0])-1);
                } else return 
false;
            }
            
            if(
$parts[0] == null || $parts[1] == null) return false;
            
$expression substr($expression,0,$pos[0]).'pow('.$parts[0].','.$parts[1].')'.substr($expression,$pos[2]+1,strlen($expression)-$pos[2]);
            return (
$expression carToPow($expression)) ? $expression false;
            
        }
        
    }
    return 
$expression;
    

__________________
"Yeah science!"
Online Science Tools

Last edited by djh101; 02-28-2012 at 06:27 PM..
djh101 is offline   Reply With Quote
Old 02-28-2012, 01:47 PM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
I don't know if I'd recommend that the caret be replaced since you'll lose the concept of the xor, but why not just use a regex to match it completely?
PHP Code:
$sEquation '452.2 ^ x + 14 - y';

$sPattern '/([a-z]|\d+(?:\.\d+)?)*\s*\^\s*([a-z]|\d+(?:\.\d+)?)/i';
$sReplace 'pow($1, $2)';

$sResult preg_replace($sPattern$sReplace$sEquation);

print 
$sResult
That will give you the same result. Granted without using a stack for this, the behaviour becomes slightly unusual if you provide an unmarked multiplication.
Fou-Lu is offline   Reply With Quote
Old 02-28-2012, 06:23 PM   PM User | #3
djh101
Regular Coder

 
djh101's Avatar
 
Join Date: May 2009
Location: Santa Clarita
Posts: 603
Thanks: 48
Thanked 63 Times in 63 Posts
djh101 is an unknown quantity at this point
This is intended for strings of standard math functions, where ^ is used for exponential expressions (and xor is not used at all). Your code works fine for standard a^b expressions, but the stack is needed for converting functions where the base or exponent is a parenthetical expression.
__________________
"Yeah science!"
Online Science Tools
djh101 is offline   Reply With Quote
Old 02-28-2012, 08:22 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Ooh yeah I do see what you mean, never thought about parenthetical expressions for the exponent, and its a mess if you have pow of pow (...of pow...*).
I know this can be done in regex as well, but I'm afraid that's beyond my skills as a matcher for sure. Stack handling even iterating is probably faster than the pattern would be anyway.
Fou-Lu is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 02:35 PM.


Advertisement
Log in to turn off these ads.