/* FormelnApplet, Berechnungen unter Anwendung einer Formel */ import java.awt.*; import java.lang.Math; import java.applet.Applet; import java.io.*; /* Kleinkram */ public class Debug { /* */ public void println(String s) {} public void print(String s) {} public void printstack(String s,double[] stack,int is) {} /* * public void println(String s) {System.out.println(s);} public void print(String s) {System.out.print(s);} public void printstack(String s,double[] stack,int is) {System.out.print(s); for(int i=0;i0 && (c=nextchar())==','); if(c!=0) fehler.print("Unexpected",c,s); ip=0; return is; } String name(String s) {int i0,i; for(i0=0;s.charAt(i0)==' ';i0++) ; for(i=i0;isalnum(s.charAt(i));i++) ; return s.substring(i0,i); } char checknextoperator() {char c=0; int i,imax,klam=0; for(i=0,imax=s.length();i0) --klam;} else if(klam==0 && !isalnum(c) && c!=' ') {snext=i+1; break;} } return c; } void ignor(char c0) {char c,c1=',',c2=')'; int i,imax,klam=0; for(i=0,imax=s.length();i0) --klam; else if(klam==0 && (c==c0 || c==c1 || c==c2)) {s=s.substring(c==c0?i+1:i); break;} } } char checknextchar() {s.trim(); if(s.length()<1) return 0; return s.charAt(0); } char nextchar() {char c; do {if(s.length()<1) return 0; c=s.charAt(0); s=s.substring(1); } while(c==' '); return c; } void nextcharundo(char c) {s=""+c+s;} boolean istzahl(String str) {char c1,c2; c1=str.charAt(0); if(c1>='0' && c1<='9') return true; if(c1=='-' || c1=='.') {if(str.length()<2) return false; c2=str.charAt(1); if(c2>='0' && c2<='9') return true; } return false; } boolean isalpha(char c1) {return (c1>='A' && c1<='Z') || (c1>='a' && c1<='z');} boolean isnum(char c1) {return (c1>='0' && c1<='9');} boolean isalnum(char c1) {return isalpha(c1)||isnum(c1);} // double stod(String x) {return new Double(x).doubleValue();} // Obige elegante Variante gibt leider Fehler bei ungueltigen Zahlen, // deshalb wird die folgende Variante gebraucht: double stod(String x) //wandle einen String in eine double-Zahl {double z=0,zexp=0,dez=0.1; int i,imax; char c; boolean vor=true,punkt=false,exp=false, negm=false,nege=false; x.trim(); for(i=0,imax=x.length(); i40) len=40; while((c1=s.charAt(0))==' ') {s=s.substring(1);} if(isalpha(c1)) //ein Symbol {ding[0]=c1; for(i=1;i': calc2(); x=(stack[is-2]>stack[is-1])?1:0; is-=2; break; case '<': calc2(); x=(stack[is-2] x="+x+" stack:",stack,is); } } void calc2() {char op; double x; boolean err=false; calc3(); while(err==false && (op=nextchar())!=0) {if(op=='+' || op=='-' || op=='>' || op=='<' || op=='?' || op==')' || op==',' || op==';' || op==':') {nextcharundo(op); return;} debug.printstack("calc2: op="+op+" stack:",stack,is);//test switch(op) {case '%': calc3(); if(checknextchar()=='^') calcpow(); x=stack[is-2]%stack[is-1]; is-=2; break; case '*': calc3(); if(checknextchar()=='^') calcpow(); x=stack[is-2]*stack[is-1]; is-=2; break; case '/': calc3(); if(checknextchar()=='^') calcpow(); if(stack[is-1]==0.0) fehler.print("division by zero",op,s); x=stack[is-2]/stack[is-1]; is-=2; break; case '^': calc3(); x=Math.pow(stack[is-2],stack[is-1]); is-=2; break; default: fehler.print("Unknown operator ",op,s); x=stack[--is]; err=true; } stack[is++]=x; debug.printstack("calc2: '"+op+"' gemacht -> x="+x+" stack:",stack,is); } } void calcpow() {char op; double x; if((op=nextchar())!='^') fehler.print("unexpected power-operator",op,s); calc2(); x=Math.pow(stack[is-2],stack[is-1]); is-=2; stack[is++]=x; } void calc3() {double x; char c; String ding=token(); debug.printstack("token() --> ding='"+ding+"' s='"+s+"' stack:",stack,is);//test if(ding.equals("(")) {calc1(); if((c=nextchar())!=')') fehler.print("Missing",')',""+c+s); x=stack[--is]; } else if(ding.equals("-")) {calc3(); x= -stack[--is];} else if(istzahl(ding)) //Zahl erkennen {x=stod(ding); debug.println("calc2: Zahl erkannt x="+x);//test } else if(ding.equals("sqrt")) //Funktionen erkennen {debug.println("calc2: sqrt erkannt");//test klammercalc(); x=Math.sqrt(stack[--is]); debug.println("sqrt gemacht -> x="+x); } else if(checknextoperator()=='=') //Zuweisungsoperator erkennen {s=s.substring(snext); calc1(); x=stack[--is]; pstore(x,ding); } else if(ding.equals("sin")) {klammercalc(); x=Math.sin(stack[--is]);} else if(ding.equals("cos")) {klammercalc(); x=Math.cos(stack[--is]);} else if(ding.equals("tan")) {klammercalc(); x=Math.tan(stack[--is]);} else if(ding.equals("asin")) {klammercalc(); x=Math.asin(stack[--is]);} else if(ding.equals("acos")) {klammercalc(); x=Math.acos(stack[--is]);} else if(ding.equals("atan")) {klammercalc(); x=Math.atan(stack[--is]);} else if(ding.equals("ln")) {klammercalc(); x=Math.log(stack[--is]);} else if(ding.equals("log")) {klammercalc(); x=Math.log(stack[--is])/Math.log(10);} else if(ding.equals("exp")) {klammercalc(); x=Math.exp(stack[--is]);} else if(ding.equals("int")) {klammercalc(); x=Math.floor(stack[--is]);} else if((j=posinparliste(ding))>=0) //Parameter erkennen {x=param[j]; debug.println("calc2: Parameter "+pname[j]+" erkannt x="+x);//test } else if(ding.equals("PI")||ding.equals("pi")) //Spezielle Konstanten erkennen {x=Math.PI;} else if(ding.equals("e")) {x=Math.E;} else if(ding.equals("GRAD")) {x=Math.PI/180;} else if(ding.equals("NL")) {x=6.023e23;} else if(ding.equals("k")) {x=1.38066e-23;} else if(ding.equals("h")) {x=6.626e-34;} else if(ding.equals("R")) {x=8.315;} else if(ding.equals("g")) {x=9.80665;} else if(ding.equals("G")) {x=6.67259e-11;} else if(ding.equals("c")) {x=299792485;} else if(ding.equals("kcal")) {x=4186.8;} //Umrechnungsfaktor von kcal in J else if(ding.equals("eV")) {x=1.602e-19;} //Umrechnungsfaktor von eV in J else {x=0; fehler.print("Unknown token",ding,s); } stack[is++]=x; } void klammercalc() {char c; if((c=nextchar())!='(') fehler.print("Missing",'(',""+c+s); calc1(); if((c=nextchar())!=')') fehler.print("Missing",')',""+c+s); } } /* Hauptprogramm */ public class FormelnApplet extends Applet { public String formel,name,startwerte; FormelFrame frame; Eval eval=new Eval(); int nparam=0,nres=0; // private int stoi(String x) {return(new Integer(x).intValue());}//convert String to int public void init() {formel=getParameter("formel"); name=getParameter("name"); startwerte=getParameter("startwerte"); frame=new FormelFrame(this); eval.ini(formel); repaint(); } public void start() {if(frame!=null) frame.show();} public void stop() {if(frame!=null) frame.hide();} public void destroy() {if(frame!=null) {frame.dispose(); frame = null; } } public void paint(Graphics g) { g.drawString(name,30,30); g.drawString(formel,30,50); g.drawString(frame.result[0].getText(),30,70); if(eval.fehler.status()) g.drawString(eval.fehler.fehlermeldung,30,90); else for(int i=1;ifbreite) fbreite=n; p.add(formel=new TextField(can.formel,fbreite)); add("Center", p = new Panel()); //add("West", p = new Panel()); for(i=0;can.startwerte.length()>0;i++) {labels[i]=gettoken(can.startwerte); startw[i]=getwert(can.startwerte); if((n=startw[i].length()+2)>breite) breite=n; can.startwerte=next(can.startwerte); } can.nparam=i; for(i=0;irbreite) rbreite=breite;//Resultatfeld mindestens so breit wie Parameter for(j=0,str=""+can.formel;j==0 || (i=str.indexOf(','))>=0;j++) {if(j>0) str=str.substring(i+1); resultlabel[j]=gettoken(str)+":"; p.add(new Label(resultlabel[j],Label.RIGHT)); p.add(result[j]=new TextField(" ",rbreite)); result[j].setEditable(false); } //add("East", p = new Panel()); p.add(new Label(" "));//Abstand p.add(new Button("Recalc")); pack(); repaint(); } public boolean handleEvent(Event evt) { //System.out.println("evt = " + evt); for(int i=0;i