Dr. Math is a PHP class that helps you with important mathematical functions: – Equation solver – Function plotter.
<?php
class math {
/************************************************************************************
* Copyright notice
*
* Dr. Mathe
*
* Copyright (C) 2000-2005 CH Software (info@chsoftware.net)
* www.chsoftware.net
* All rights reserved
* For more information go to:
* www.chsoftware.net/en/useware/conditions/conditions.htm
*
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* The GNU General Public License can be found at
* http://www.gnu.org/licenses/gpl.html
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*************************************************************************************/
/** Class for some math functions
*
* This class allows you, to use some special math functions, eg. solving easy equations or drawing a graph
*
* Revised on 10/5/2004 (de: 5.10.2004) by Cornelius Herzog
*
* @author Cornelius Herzog (c.herzog@chsoftware.net)
*
*/
/**
* Settings for the program parts
*/
/** Settings for the solver **/
var $maxbound = 1000; //maximal number for intervalcalculation
var $minbound = -1000; //minimal number for intervalcalculation
var $debug_output = FALSE; //debug output (max, min, middle, result)
var $max_iterations = 100000; //maximum number of interations
var $start_value = 0; //startvalue of the middle
var $intelligent_search = TRUE; //Use the intelligent search?
var $return_human = TRUE;
/**
* General vars
*/
var $done_iterations; //returns the number of done equations
var $parsed_term; //contains the last parsed term
/**
* Allowed functions. All other commands are filtered of
*/
var $allowed_commands = array("abs(#)","acos(#)","asin(#)","atan(#)","atan2(#,#)","base_convert(#,#,#)","bindec(#)","ceil(#)","cos(#)","decbin(#)","dechex(#)","decoct(#)","deg2rad(#)","exp(#)","floor(#)","hexdec(#)","log(#)","log10(#)","octdec(#)","pi","pow(#,#)","rad2deg(#)","rand(#,#)","round(#,#)","sin(#)","sqrt(#)","tan(#)");
/**
* Solve an equation
*
* @param eq string equation term
* @param var string name of the var by the term should be solved
* @return result
*/
function solve($eq,$var) {
if(!$eq OR !$var) { $this->errorhandler(2,"solve"); }
if(!stristr($eq,"=")) {
$this->errorhandler(1);
}
$t = explode("=",$eq);
$l = trim($t[0]);
$r = trim($t[1]);
$l = $this->parse_term($l);
$r = $this->parse_term($r);
if(stristr($l,$var) AND stristr($r,$var)) {
$term = $l . "-(" . $r . ")";
$sol = $this->intervalapprox($term,0,$var);
}elseif((stristr($l,$var) AND !stristr($r,$var)) OR (!stristr($l,$var) AND stristr($r,$var))) {
if(stristr($l,$var)) {
$sol = $this->intervalapprox($l,$r,$var);
}else{
$sol = $this->intervalapprox($r,$l,$var);
}
}elseif(!stristr($l,$var) AND !stristr($r,$var)) {#
if($l == $r) {
return "Infinite solutions";
}else{
return "No solution";
}
}else{
errorhandler(3,$eq);
}
if($this->return_human == TRUE and stristr($sol,".")) {
$soln = $this->square2dec($sol);
if($soln == $sol) {
$sol = $this->dec2frac($sol);
}else{
$sol = $soln;
}
return $sol;
}else{
return $sol;
}
}
/**
* Do an interval approximation
*
* @param expr string equation term
* @param val string value the terme must be
* @param var string name of the var by the term should be solved
* @return result
*/
function intervalapprox($expr,$val,$var) {
$expr = strip_tags($expr);
$expr = "\$res = " . $expr .";";
$max = $this->maxbound;
$min = $this->minbound;
$count = 0;
$middle = $this->start_value;
while($sol == "") {
$$var = $middle;
eval($expr);
if($this->debug_output == TRUE) {
echo "Max: $max <br> Min: $min <br> Middle: $middle <br>Result: $res<hr>";
}
if($this->intelligent_search == TRUE) {
if(round($res,10) == $val) {
$this->done_iterations = $count;
return round($middle,10);
}else{
$isol = $this->intelligent_search($expr,$val,$var,$middle);
if(strlen($isol) != 0) {
$this->done_iterations = $count;
return round($middle,$isol);
}
}
}else{
if(round($res,10) == $val) {
$this->done_iterations = $count;
return round($middle,10);
}
}
if($res > $val) {
$max = $middle;
}
if($res < $val) {
$min = $middle;
}
$middle = ($max + $min) / 2;
$count++;
if($count == $this->max_iterations) { $this->errorhandler("4"); return ""; }
}
}
/**
* Makes a rooted decimal number to his root
*
* @param n double input number
* @return double
*/
function square2dec($n) {
if(!stristr(round($n * $n,2),".")) {
return "sqr(" . round($n * $n,2) . ")";
}else{
return $n;
}
}
/**
* Do an intelligent check of the given number in the equ
*
* @param expr string equation term
* @param val double the result that must come out
* @param var string the function variable
* @param testval double the value to test with
* @return double solution
*/
function intelligent_search($expr,$val,$var,$testval) {
$$var = $testval;
eval($expr);
if($res == $val) { return 0;}
if(stristr($testval,".")) {
for($rstellen=10;$rstellen>=0;$rstellen--) {
$test = round($testval,$rstellen);
$$var = $test;
eval($expr);
if($res == $val) { return $rstellen;}
}
}else{
$$var = $testval;
eval($expr);
if($res == $val) { return 0;}
}
return "";
}
/**
* Makes a term readable for the interpreter
*
* @param expr string equation term
* @return string
* @return this->parsed_term, string
*/
function parse_term($t) {
$t = strip_tags($t); //remove tags, prevent cross scripting
$t = strtolower($t); //all to lower case
$nropen = substr_count($t,"("); //check if the number of brackets is the same
$nrclose = substr_count($t,")");
if($nropen != $nrclose) {
$arg[0] = $nropen;
$arg[1] = $nrclose;
$this->errorhandler("5",$arg);
}
for($x=0;$x<strlen($t);$x++) { //run for all chars
$pc = $t[$x-1]; //previous char of the actual
$tc = $t[$x]; //actual char
$nc = $t[$x+1]; //next char
if(!$this->is_number($tc)) { //just parse if this char is not a number
//many if conditions weight out what to do, no comments.
if(($this->is_number($nc) || !$this->is_char($nc)) && !$this->is_char($pc) && !$this->is_operator($tc) && $pc != "\$") {
$t = $this->prefix($t,$x,"\$");
}
if($tc == "(" and $this->is_number($pc)) {
$t = $this->prefix($t,$x,"*");
}
if($this->is_number($pc) && ($tc == "\$" || $this->is_char($tc))) {
$t = $this->prefix($t,$x,"*");
}
if($this->is_char($tc) && $pc == ")") {
$t = $this->prefix($t,$x,"*");
}
if($tc == ")" && $this->is_char($pc) && $t[$x-2] == "(") {
$t = $this->prefix($t,$x-1,"\$");
}
//checks if we have a function in the term as if cos, sin or sth like that
for($y=0;$y<sizeof($this->allowed_commands);$y++) {
if($tc . $nc == substr($this->allowed_commands[$y],0,2)) {
$tmp = explode("(",$this->allowed_commands[$y]);
$cmdlen = strlen($tmp[0]);
$cmdrest = substr($t,$x);
$endcmd = strpos($cmdrest,")") + 1;
$fullcmd = substr($cmdrest,0,$endcmd);
$n_args = substr_count($this->allowed_commands[$y],"#");
$g_args = substr_count($fullcmd,",") + 1;
if($n_args != $g_args) {
$this->errorhandler(2,'"'.$tmp[0].'". You gave '.$g_args.' argument(s) but there is needed '.$n_args.' argument(s)');
}
$x = $x + $cmdlen + 1;
}
}
}
}
$t = str_replace(")\$",")*\$",$t); //add a * between a bracket and a variable
$t = str_replace(")(",")*(",$t); //add a * between two brackets
//fixes the bug, that there is no * between a number an a closing bracket
for($x=0;$x<strlen($t);$x++) {
$pc = $t[$x-1];
$tc = $t[$x];
$nc = $t[$x+1];
if($this->is_number($tc) && $pc == ")") {
$t = $this->prefix($t,$x,"*");
}
}
//this for statement makes the exponents working, because php doesn't know ^. eg (x-2)^2 = (x-2)*(x-2)
for($x=0;$x<strlen($t);$x++) {
$pc = $t[$x-1];
$tc = $t[$x];
$nc = $t[$x+1];
if($tc == "^") {
$i=1;
while($this->is_number($t[$x+$i])) {
$i++;
}
$ex = str_replace("^","",substr($t,$x,$i));
if($this->is_char($pc) && $t[$x-2] == "\$") {
$pattern = substr($t,$x-2,2);
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}elseif($pc == ")") {
$tmpstr = substr($t,0,$x);
$cb = 0;
$ob = 0;
for($k=strlen($tmpstr)-1;$k>=0;$k--) {
if($tmpstr[$k] == ")") {
$cb++;
}
if($tmpstr[$k] == "(") {
$ob++;
}
if($ob != 0 && $cb != 0 && $cb == $ob) {
$pos = $k;
break;
}
}
$pattern = substr($tmpstr,$pos);
if($this->is_char($prepos) AND $pprepos == "\$") {
$pattern = substr($tmpstr,$pos);
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}else{
$i=1;
if($z == 1) { echo $tmpstr . "<br>"; }
while($this->is_char($t[$pos-$i])) {
$i++;
}
$pattern = substr($tmpstr,$pos-$i+1);
$bopencount = substr_count($pattern,"(");
$bclosecount = substr_count($pattern,")");
if($bopencount != $bclosecount) {
$pattern = "(" . $pattern;
}
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}
}elseif($this->is_number($pc)) {
$tmpstr = substr($t,0,$x);
$i=1;
while($this->is_number($t[$x-$i])) {
$i++;
}
$pattern = substr($tmpstr,-$i+1);
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}
}
}
$this->parsed_term = $t;
return $t;
}
/**
* Repeats a pattern x times
*
* @param pattern string the pattern to repeat
* @param glue string glue the pattern with this string
* @param nr double number of repeating the pattern
* @return string
*/
function pattern_repeater($pattern,$glue,$nr) {
for($i=0;$i<$nr;$i++) {
$str.= $pattern . $glue;
}
if(substr($str,-1) == $glue) { $str = substr($str,0,-1); }
return $str;
}
/**
* Prefix a char in a string with a char or string
*
* @param str string input string
* @param pos double
* @return string
*/
function prefix($str,$pos,$prefix) {
$v = substr($str,0,$pos);
$h = substr($str,$pos);
$str = $v . $prefix . $h;
return $str;
}
/**
* Check if the given char is an operator
*
* @param n char input char to check
* @return boolean
*/
function is_operator($n) {
if($n == "+" || $n == "-" || $n == "*" || $n == "/" || $n == "^" || $n == "(" || $n == ")") {
return true;
}else{
return false;
}
}
/**
* Check if the given char is a char
*
* @param n char input char to check
* @return boolean
*/
function is_char($n) {
$v = ord($n);
if(97 <= $v && 122 >= $v) {
return true;
}else{
return false;
}
}
/**
* Check if the given char is a number
*
* @param n char input char to check
* @return boolean
*/
function is_number($n) {
$v = ord($n);
if((48 <= $v && 57 >= $v) || $n == ".") {
return true;
}else{
return false;
}
}
/**
* Convert a decimal number to a fraction
*
* @param n double number
* @return fraction
*/
function dec2frac($n,$format = "total") {
$n = str_replace(",",".",$n);
$t = explode(".",$n);
$full = $t[0];
$part = $t[1];
if($format == "total") {
$zaehler = str_replace(".","",$n);
if(substr($zaehler,0,1) == "0") { $zaehler = substr($zaehler,1); }
$nenner = "1";
$nenner = str_pad($nenner, strlen($part)+1,"0");
$gcd = $this->gcd($zaehler,$nenner);
if($gcd != "") {
$zaehler = $zaehler / $gcd;
$nenner = $nenner / $gcd;
}
return $zaehler . "/" . $nenner;
}else{
$zaehler = $part;
$nenner = "1";
$nenner = str_pad($nenner, strlen($part)+1,"0");
$gcd = $this->gcd($zaehler,$nenner);
if($gcd != "") {
$zaehler = $zaehler / $gcd;
$nenner = $nenner / $gcd;
}
return $full . " " . $zaehler . "/" . $nenner;
}
}
/**
* get the greatest common divisor of two numbers
*
* @param v1 double number 1
* @param v2 double number 2
* @return gcd
*/
function gcd($v1,$v2) {
do {
$d = $v1 % $v2;
if($d == 0) { return $v2; }
$v1 = $v2;
$v2 = $d;
} while($d != 0);
}
function errorhandler($errnr,$i = "") {
switch($errnr) {
case 1:
$err = "Missing =. Can't proceed";
$p = false;
break;
case 2:
$err = "Not the right number of arguments for function $i. Can't proceed.";
$p = false;
break;
case 3:
$err = "Unknow type of equation. Can't proceed";
$p = false;
break;
case 4:
$err = "No solution found for the given equation";
$p = true;
break;
case 5:
$err = "Not the same number of brackets. You have ".$i[0] . " opening bracket(s) and ".$i[1] ." closing bracket(s)!";
break;
case 6:
$err = "The term $i could not be parsed. Please check it for errors!";
$p = true;
break;
}
echo '<div style="font-family: Verdana; font-size: 10pt; font-weight:bold; color:red; background-color:lightblue;">'.$err.'</div>';
if($p == false) {
die();
}
}
}
?>
&nbsp;
class math {
/************************************************************************************
* Copyright notice
*
* Dr. Mathe
*
* Copyright (C) 2000-2005 CH Software (info@chsoftware.net)
* www.chsoftware.net
* All rights reserved
* For more information go to:
* www.chsoftware.net/en/useware/conditions/conditions.htm
*
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* The GNU General Public License can be found at
* http://www.gnu.org/licenses/gpl.html
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*************************************************************************************/
/** Class for some math functions
*
* This class allows you, to use some special math functions, eg. solving easy equations or drawing a graph
*
* Revised on 10/5/2004 (de: 5.10.2004) by Cornelius Herzog
*
* @author Cornelius Herzog (c.herzog@chsoftware.net)
*
*/
/**
* Settings for the program parts
*/
/** Settings for the solver **/
var $maxbound = 1000; //maximal number for intervalcalculation
var $minbound = -1000; //minimal number for intervalcalculation
var $debug_output = FALSE; //debug output (max, min, middle, result)
var $max_iterations = 100000; //maximum number of interations
var $start_value = 0; //startvalue of the middle
var $intelligent_search = TRUE; //Use the intelligent search?
var $return_human = TRUE;
/**
* General vars
*/
var $done_iterations; //returns the number of done equations
var $parsed_term; //contains the last parsed term
/**
* Allowed functions. All other commands are filtered of
*/
var $allowed_commands = array("abs(#)","acos(#)","asin(#)","atan(#)","atan2(#,#)","base_convert(#,#,#)","bindec(#)","ceil(#)","cos(#)","decbin(#)","dechex(#)","decoct(#)","deg2rad(#)","exp(#)","floor(#)","hexdec(#)","log(#)","log10(#)","octdec(#)","pi","pow(#,#)","rad2deg(#)","rand(#,#)","round(#,#)","sin(#)","sqrt(#)","tan(#)");
/**
* Solve an equation
*
* @param eq string equation term
* @param var string name of the var by the term should be solved
* @return result
*/
function solve($eq,$var) {
if(!$eq OR !$var) { $this->errorhandler(2,"solve"); }
if(!stristr($eq,"=")) {
$this->errorhandler(1);
}
$t = explode("=",$eq);
$l = trim($t[0]);
$r = trim($t[1]);
$l = $this->parse_term($l);
$r = $this->parse_term($r);
if(stristr($l,$var) AND stristr($r,$var)) {
$term = $l . "-(" . $r . ")";
$sol = $this->intervalapprox($term,0,$var);
}elseif((stristr($l,$var) AND !stristr($r,$var)) OR (!stristr($l,$var) AND stristr($r,$var))) {
if(stristr($l,$var)) {
$sol = $this->intervalapprox($l,$r,$var);
}else{
$sol = $this->intervalapprox($r,$l,$var);
}
}elseif(!stristr($l,$var) AND !stristr($r,$var)) {#
if($l == $r) {
return "Infinite solutions";
}else{
return "No solution";
}
}else{
errorhandler(3,$eq);
}
if($this->return_human == TRUE and stristr($sol,".")) {
$soln = $this->square2dec($sol);
if($soln == $sol) {
$sol = $this->dec2frac($sol);
}else{
$sol = $soln;
}
return $sol;
}else{
return $sol;
}
}
/**
* Do an interval approximation
*
* @param expr string equation term
* @param val string value the terme must be
* @param var string name of the var by the term should be solved
* @return result
*/
function intervalapprox($expr,$val,$var) {
$expr = strip_tags($expr);
$expr = "\$res = " . $expr .";";
$max = $this->maxbound;
$min = $this->minbound;
$count = 0;
$middle = $this->start_value;
while($sol == "") {
$$var = $middle;
eval($expr);
if($this->debug_output == TRUE) {
echo "Max: $max <br> Min: $min <br> Middle: $middle <br>Result: $res<hr>";
}
if($this->intelligent_search == TRUE) {
if(round($res,10) == $val) {
$this->done_iterations = $count;
return round($middle,10);
}else{
$isol = $this->intelligent_search($expr,$val,$var,$middle);
if(strlen($isol) != 0) {
$this->done_iterations = $count;
return round($middle,$isol);
}
}
}else{
if(round($res,10) == $val) {
$this->done_iterations = $count;
return round($middle,10);
}
}
if($res > $val) {
$max = $middle;
}
if($res < $val) {
$min = $middle;
}
$middle = ($max + $min) / 2;
$count++;
if($count == $this->max_iterations) { $this->errorhandler("4"); return ""; }
}
}
/**
* Makes a rooted decimal number to his root
*
* @param n double input number
* @return double
*/
function square2dec($n) {
if(!stristr(round($n * $n,2),".")) {
return "sqr(" . round($n * $n,2) . ")";
}else{
return $n;
}
}
/**
* Do an intelligent check of the given number in the equ
*
* @param expr string equation term
* @param val double the result that must come out
* @param var string the function variable
* @param testval double the value to test with
* @return double solution
*/
function intelligent_search($expr,$val,$var,$testval) {
$$var = $testval;
eval($expr);
if($res == $val) { return 0;}
if(stristr($testval,".")) {
for($rstellen=10;$rstellen>=0;$rstellen--) {
$test = round($testval,$rstellen);
$$var = $test;
eval($expr);
if($res == $val) { return $rstellen;}
}
}else{
$$var = $testval;
eval($expr);
if($res == $val) { return 0;}
}
return "";
}
/**
* Makes a term readable for the interpreter
*
* @param expr string equation term
* @return string
* @return this->parsed_term, string
*/
function parse_term($t) {
$t = strip_tags($t); //remove tags, prevent cross scripting
$t = strtolower($t); //all to lower case
$nropen = substr_count($t,"("); //check if the number of brackets is the same
$nrclose = substr_count($t,")");
if($nropen != $nrclose) {
$arg[0] = $nropen;
$arg[1] = $nrclose;
$this->errorhandler("5",$arg);
}
for($x=0;$x<strlen($t);$x++) { //run for all chars
$pc = $t[$x-1]; //previous char of the actual
$tc = $t[$x]; //actual char
$nc = $t[$x+1]; //next char
if(!$this->is_number($tc)) { //just parse if this char is not a number
//many if conditions weight out what to do, no comments.
if(($this->is_number($nc) || !$this->is_char($nc)) && !$this->is_char($pc) && !$this->is_operator($tc) && $pc != "\$") {
$t = $this->prefix($t,$x,"\$");
}
if($tc == "(" and $this->is_number($pc)) {
$t = $this->prefix($t,$x,"*");
}
if($this->is_number($pc) && ($tc == "\$" || $this->is_char($tc))) {
$t = $this->prefix($t,$x,"*");
}
if($this->is_char($tc) && $pc == ")") {
$t = $this->prefix($t,$x,"*");
}
if($tc == ")" && $this->is_char($pc) && $t[$x-2] == "(") {
$t = $this->prefix($t,$x-1,"\$");
}
//checks if we have a function in the term as if cos, sin or sth like that
for($y=0;$y<sizeof($this->allowed_commands);$y++) {
if($tc . $nc == substr($this->allowed_commands[$y],0,2)) {
$tmp = explode("(",$this->allowed_commands[$y]);
$cmdlen = strlen($tmp[0]);
$cmdrest = substr($t,$x);
$endcmd = strpos($cmdrest,")") + 1;
$fullcmd = substr($cmdrest,0,$endcmd);
$n_args = substr_count($this->allowed_commands[$y],"#");
$g_args = substr_count($fullcmd,",") + 1;
if($n_args != $g_args) {
$this->errorhandler(2,'"'.$tmp[0].'". You gave '.$g_args.' argument(s) but there is needed '.$n_args.' argument(s)');
}
$x = $x + $cmdlen + 1;
}
}
}
}
$t = str_replace(")\$",")*\$",$t); //add a * between a bracket and a variable
$t = str_replace(")(",")*(",$t); //add a * between two brackets
//fixes the bug, that there is no * between a number an a closing bracket
for($x=0;$x<strlen($t);$x++) {
$pc = $t[$x-1];
$tc = $t[$x];
$nc = $t[$x+1];
if($this->is_number($tc) && $pc == ")") {
$t = $this->prefix($t,$x,"*");
}
}
//this for statement makes the exponents working, because php doesn't know ^. eg (x-2)^2 = (x-2)*(x-2)
for($x=0;$x<strlen($t);$x++) {
$pc = $t[$x-1];
$tc = $t[$x];
$nc = $t[$x+1];
if($tc == "^") {
$i=1;
while($this->is_number($t[$x+$i])) {
$i++;
}
$ex = str_replace("^","",substr($t,$x,$i));
if($this->is_char($pc) && $t[$x-2] == "\$") {
$pattern = substr($t,$x-2,2);
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}elseif($pc == ")") {
$tmpstr = substr($t,0,$x);
$cb = 0;
$ob = 0;
for($k=strlen($tmpstr)-1;$k>=0;$k--) {
if($tmpstr[$k] == ")") {
$cb++;
}
if($tmpstr[$k] == "(") {
$ob++;
}
if($ob != 0 && $cb != 0 && $cb == $ob) {
$pos = $k;
break;
}
}
$pattern = substr($tmpstr,$pos);
if($this->is_char($prepos) AND $pprepos == "\$") {
$pattern = substr($tmpstr,$pos);
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}else{
$i=1;
if($z == 1) { echo $tmpstr . "<br>"; }
while($this->is_char($t[$pos-$i])) {
$i++;
}
$pattern = substr($tmpstr,$pos-$i+1);
$bopencount = substr_count($pattern,"(");
$bclosecount = substr_count($pattern,")");
if($bopencount != $bclosecount) {
$pattern = "(" . $pattern;
}
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}
}elseif($this->is_number($pc)) {
$tmpstr = substr($t,0,$x);
$i=1;
while($this->is_number($t[$x-$i])) {
$i++;
}
$pattern = substr($tmpstr,-$i+1);
$nex = $this->pattern_repeater($pattern,"*",$ex);
$t = str_replace($pattern . "^" . $ex,$nex,$t);
}
}
}
$this->parsed_term = $t;
return $t;
}
/**
* Repeats a pattern x times
*
* @param pattern string the pattern to repeat
* @param glue string glue the pattern with this string
* @param nr double number of repeating the pattern
* @return string
*/
function pattern_repeater($pattern,$glue,$nr) {
for($i=0;$i<$nr;$i++) {
$str.= $pattern . $glue;
}
if(substr($str,-1) == $glue) { $str = substr($str,0,-1); }
return $str;
}
/**
* Prefix a char in a string with a char or string
*
* @param str string input string
* @param pos double
* @return string
*/
function prefix($str,$pos,$prefix) {
$v = substr($str,0,$pos);
$h = substr($str,$pos);
$str = $v . $prefix . $h;
return $str;
}
/**
* Check if the given char is an operator
*
* @param n char input char to check
* @return boolean
*/
function is_operator($n) {
if($n == "+" || $n == "-" || $n == "*" || $n == "/" || $n == "^" || $n == "(" || $n == ")") {
return true;
}else{
return false;
}
}
/**
* Check if the given char is a char
*
* @param n char input char to check
* @return boolean
*/
function is_char($n) {
$v = ord($n);
if(97 <= $v && 122 >= $v) {
return true;
}else{
return false;
}
}
/**
* Check if the given char is a number
*
* @param n char input char to check
* @return boolean
*/
function is_number($n) {
$v = ord($n);
if((48 <= $v && 57 >= $v) || $n == ".") {
return true;
}else{
return false;
}
}
/**
* Convert a decimal number to a fraction
*
* @param n double number
* @return fraction
*/
function dec2frac($n,$format = "total") {
$n = str_replace(",",".",$n);
$t = explode(".",$n);
$full = $t[0];
$part = $t[1];
if($format == "total") {
$zaehler = str_replace(".","",$n);
if(substr($zaehler,0,1) == "0") { $zaehler = substr($zaehler,1); }
$nenner = "1";
$nenner = str_pad($nenner, strlen($part)+1,"0");
$gcd = $this->gcd($zaehler,$nenner);
if($gcd != "") {
$zaehler = $zaehler / $gcd;
$nenner = $nenner / $gcd;
}
return $zaehler . "/" . $nenner;
}else{
$zaehler = $part;
$nenner = "1";
$nenner = str_pad($nenner, strlen($part)+1,"0");
$gcd = $this->gcd($zaehler,$nenner);
if($gcd != "") {
$zaehler = $zaehler / $gcd;
$nenner = $nenner / $gcd;
}
return $full . " " . $zaehler . "/" . $nenner;
}
}
/**
* get the greatest common divisor of two numbers
*
* @param v1 double number 1
* @param v2 double number 2
* @return gcd
*/
function gcd($v1,$v2) {
do {
$d = $v1 % $v2;
if($d == 0) { return $v2; }
$v1 = $v2;
$v2 = $d;
} while($d != 0);
}
function errorhandler($errnr,$i = "") {
switch($errnr) {
case 1:
$err = "Missing =. Can't proceed";
$p = false;
break;
case 2:
$err = "Not the right number of arguments for function $i. Can't proceed.";
$p = false;
break;
case 3:
$err = "Unknow type of equation. Can't proceed";
$p = false;
break;
case 4:
$err = "No solution found for the given equation";
$p = true;
break;
case 5:
$err = "Not the same number of brackets. You have ".$i[0] . " opening bracket(s) and ".$i[1] ." closing bracket(s)!";
break;
case 6:
$err = "The term $i could not be parsed. Please check it for errors!";
$p = true;
break;
}
echo '<div style="font-family: Verdana; font-size: 10pt; font-weight:bold; color:red; background-color:lightblue;">'.$err.'</div>';
if($p == false) {
die();
}
}
}
?>
&nbsp;