//*************************************************************************************
// 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;
}