//*************************************************************************************
// evalMyJava :(Javaでの自作の eval() 関数)
// All rights reserved. Copyright (C) 2006 YokahiYokatoki
//*************************************************************************************
// 自作の eval関数---------------------------------------------------------------------
public double evalMyJava(double x, String equation)
{
String equ="("+equation+")"; // ( )でくくる
equ=equ.replace("Math.PI", Double.toString(Math.PI)); // πを数値に置換
equ=equ.replace("Math.E", Double.toString(Math.E)); // eを数値に置換
equ=equ.replace("exp", "ezp"); // exp を ezp に置換しておく
equ=equ.replace("x", Double.toString(x)); // xを数字に置換
equ=equ.replace("ezp", "exp"); // ezp を exp に戻す
int m0=0; // -- の処理-------(注釈:x を数値に置換したので、x が負値のとき --3.1 のようになっている)
while(true)
{
int m1=equ.indexOf("--", m0); if(m1<0){break;}
if(m1==0 || equ.charAt(m1-1)==40 || equ.charAt(m1-1)==42 || equ.charAt(m1-1)==47 || equ.charAt(m1-1)==43 || equ.charAt(m1-1)==44)
{
equ=equ.substring(0, m1) + equ.substring(m1+2); // -- を 取る
}
else
{
equ=equ.substring(0, m1) + "+" + equ.substring(m1+2); // -- を + に置換
}
m0=m1; if(m0>equ.length()-1){break;}
}
m0=0; // - の処理-------
while(true)
{
int m1=equ.indexOf("-", m0); if(m1<0){break;}
if(m1==0 || equ.charAt(m1-1)==40 || equ.charAt(m1-1)==42 || equ.charAt(m1-1)==47 || equ.charAt(m1-1)==43 || equ.charAt(m1-1)==44)
{
m0=m1+1;
}
else
{
equ=equ.substring(0, m1) + "+(-1)*" + equ.substring(m1+1); // -a、-Math.sin(A) などを +(-1)*a、 +(-1)*Math.sin(A) などに置き換える
m0=m1+6;
}
if(m0>equ.length()-1){break;}
}
double valResult=Double.parseDouble(evalMy0(equ));
return valResult;
}
//----------------------------------------------------------------------------------
public String evalMy0(String equation)
{
String equ=equation;
while(true) // 最内側の( ) から計算する(注釈:最内側( )内には、Math.…() のようなものはない)
{
int n1=equ.indexOf(")"); if(n1<0){break;} // ) の検索
int n2=equ.lastIndexOf("(", n1-1); // ( に対応する ) の検索
if(n2<0){break;}
String str=equ.substring(n2+1, n1); // ( )内の文字
int ne0=str.indexOf(","); // ( )内の , の検索
double val=0;
if(ne0>=0) // ( )内に , があるので、 Math.log(A,B) or Math.pow(A,B) の処理
{
if((equ.substring(n2-3, n2)).equals("log")) // Math.log(A,B) のとき
{
String strA=str.substring(0, ne0); // Math.log(A,B)の A の文字
double valA=Double.parseDouble(evalMy0("("+strA+")")); // (注:再帰である)
String strB=str.substring(ne0+1); // Math.log(A,B)の B の文字
double valB=Double.parseDouble(evalMy0("("+strB+")")); //(注:再帰である)
val=Math.log(valB)/Math.log(valA);
equ=equ.replace("Math.log("+strA+","+strB+")", Double.toString(val));
}
else if((equ.substring(n2-3, n2)).equals("pow")) // Math.pow(A,B) のとき
{
String strA=str.substring(0, ne0); // Math.pow(A,B)の A の文字
double valA=Double.parseDouble(evalMy0("("+strA+")")); // (注:再帰である)
String strB=str.substring(ne0+1); // Math.pow(A,B)の B の文字
double valB=Double.parseDouble(evalMy0("("+strB+")")); //(注:再帰である)
val=Math.pow(valA,valB);
equ=equ.replace("Math.pow("+strA+","+strB+")", Double.toString(val));
}
}
else
{
int check0=0; // strが数値(数字)かどうかチェック(str="-3.7" なら 数値なので 0 とする)
for(int i=0; i< str.length(); i++)
{
if(i==0)
{
if((str.charAt(0)<48 || str.charAt(0)>57) && str.charAt(0) !=46 && str.charAt(0) !=43 && str.charAt(0) !=45){check0=1; break;}
}
else
{
if((str.charAt(i)<48 || str.charAt(i)>57) && str.charAt(i) !=46){check0=1; break;}
}
}
if(check0==1)
{
val=evalMy1(str); // ( ) の処理をし数値をもとめる
}
else
{
val=Double.parseDouble(str); // 文字を数値に変換
}
if(n2-8>=0)
{
String str1=equ.substring(n2-8, n2);
if(str1.equals("Math.sin")){val=Math.sin(val); equ=equ.replace("Math.sin("+str+")", Double.toString(val)); n2-=8;}
else if(str1.equals("Math.cos")){val=Math.cos(val); equ=equ.replace("Math.cos("+str+")", Double.toString(val)); n2-=8;}
else if(str1.equals("Math.tan")){val=Math.tan(val); equ=equ.replace("Math.tan("+str+")", Double.toString(val)); n2-=8;}
else if(str1.equals("ath.asin")){val=Math.asin(val); equ=equ.replace("Math.asin("+str+")", Double.toString(val)); n2-=9;}
else if(str1.equals("ath.acos")){val=Math.acos(val); equ=equ.replace("Math.acos("+str+")", Double.toString(val)); n2-=9;}
else if(str1.equals("ath.atan")){val=Math.atan(val); equ=equ.replace("Math.atan("+str+")", Double.toString(val)); n2-=9;}
else if(str1.equals("Math.log")){val=Math.log(val); equ=equ.replace("Math.log("+str+")", Double.toString(val)); n2-=8;}
else if(str1.equals("Math.exp")){val=Math.exp(val); equ=equ.replace("Math.exp("+str+")", Double.toString(val)); n2-=8;}
else if(str1.equals("Math.abs")){val=Math.abs(val); equ=equ.replace("Math.abs("+str+")", Double.toString(val)); n2-=8;}
else if(str1.equals("ath.sqrt")){val=Math.sqrt(val); equ=equ.replace("Math.sqrt("+str+")", Double.toString(val)); n2-=9;}
else {equ=equ.replace("("+str+")", Double.toString(val));} // ( ) を取る
}
else
{
equ=equ.replace("("+str+")", Double.toString(val)); // ( ) を取る
}
}
}
return equ;
}
// * と / のみからなる数式の いくつかの和、差からなる式の処理----------------
public double evalMy1(String equation)
{
double val=0;
while(true)
{
String equ0="";
int n0=equation.indexOf("+");
if(n0<0){equ0=equation;} else {equ0=equation.substring(0, n0);} // 最初の + より前の項
val+=evalMy2(equ0);
if(n0<0){break;} else {equation=equation.substring(n0+1);} // 最初の + より以降の項
}
return val;
}
// * と / のみからなる数式についての処理-----------------------------------
public double evalMy2(String equation)
{
double val0=1;
while(true)
{
String equ0="";
int n0=equation.indexOf("*");
if(n0<0){equ0=equation;} else {equ0=equation.substring(0, n0);} // 最初の * より前の項
int kai=0;
double val1=1;
while(true) // / を含んだ項の計算
{
String equ1="";
int n1=equ0.indexOf("/");
if(n1<0){equ1=equ0;} else {equ1=equ0.substring(0, n1);} // 最初の / より前の項
if(kai==0){val1=Double.parseDouble(equ1);} else {val1/=Double.parseDouble(equ1);}
if(n1<0){break;} else {kai++; equ0=equ0.substring(n1+1);} // 最初の / より以降の項
}
val0*=val1;
if(n0<0){break;} else {equation=equation.substring(n0+1);} // 最初の * より以降の項
}
return val0;
}