package gve.calc.formula;
import java.awt.*;
public class OperatorPow extends InfixBinaryOp {
public String getName() { return "^"; }
public int getPri() { return 2000; }
public OperatorPow(Part l,Part r) {
super(l,r);
}
if r in N (integer) and r != 0, use this method |
private Interval evalN(Interval l,double r) {
if (r == 1) return new Interval(l.low,l.high,l.openLow,l.openHigh);
double pow1 = Math.pow(l.low,r);
double pow2 = Math.pow(l.high,r);
if ( (((long)r)%2) == 0) { // even: x^2, x^4, ...
if (l.low<0 && 0<l.high) // l has 0 inside it
if (pow1 > pow2) return new Interval(0,pow1,false,l.openLow);
else return new Interval(0,pow2,false,l.openHigh);
else if (l.high < 0) // l negative
return new Interval(pow2,pow1,l.openHigh,l.openLow);
else // l positive
return new Interval(pow1,pow2,l.openLow,l.openHigh);
} else { //odd: ...^3, ...^5, ...^7
return new Interval(pow1,pow2,l.openLow,l.openHigh);
}
}
public Part evaluate(Evaluator ev) {
Part l = left.evaluate(ev);
Part r = right.evaluate(ev);
if (l instanceof Real && r instanceof Real) {
try {
return new Real(Math.pow(((Real)l).doubleValue,((Real)r).doubleValue));
} catch (ArithmeticException exc) {}
} else if (l instanceof Interval && r instanceof Real) {
double pow = ((Real)r).doubleValue;
if (pow == 0) return new Real(0);
Interval lef = (Interval)l;
if (pow == 1) return new Interval(lef.low,lef.high,lef.openLow,lef.openHigh);
if (pow == (long)pow) { // r is integer
if (pow > 0) return evalN(lef,pow);
if (pow < 0) return new Fraction(new Real(1),evalN(lef,-pow)).evaluate(ev);
}
}
return new OperatorPow(l,r);
}
public Component createView(FormulaView view) {
return new OperatorPowView(this,view);
}
}