Operator.java
/*
* Copyright 2014 Frank Asseg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.objecthunter.exp4j.operator;
import java.io.Serial;
import java.io.Serializable;
/**
* Class representing operators that can be used in an expression
*/
public abstract class Operator implements Serializable {
@Serial
private static final long serialVersionUID = -2212179357073818713L;
/**
* The precedence value for the addition operation (default: {@value})
*/
public static final int PRECEDENCE_ADDITION = 500;
/**
* The precedence value for the subtraction operation (default: {@value})
*/
public static final int PRECEDENCE_SUBTRACTION = PRECEDENCE_ADDITION;
/**
* The precedence value for the multiplication operation (default: {@value})
*/
public static final int PRECEDENCE_MULTIPLICATION = 1000;
/**
* The precedence value for the division operation (default: {@value})
*/
public static final int PRECEDENCE_DIVISION = PRECEDENCE_MULTIPLICATION;
/**
* The precedence value for the modulo operation (default: {@value})
*/
public static final int PRECEDENCE_MODULO = PRECEDENCE_DIVISION;
/**
* The precedence value for the power operation (default: {@value})
*/
public static final int PRECEDENCE_POWER = 10000;
/**
* The precedence value for the unary minus operation (default: {@value})
*/
public static final int PRECEDENCE_UNARY_MINUS = 5000;
/**
* The precedence value for the unary plus operation (default: {@value})
*/
public static final int PRECEDENCE_UNARY_PLUS = PRECEDENCE_UNARY_MINUS;
/**
* The precedence value for the boolean not (default: {@value})
*/
public static final int PRECEDENCE_NOT = PRECEDENCE_ADDITION - 200;
/**
* The precedence value for the boolean and (default: {@value})
*/
public static final int PRECEDENCE_AND = PRECEDENCE_ADDITION - 300;
/**
* The precedence value for the boolean or (default: {@value})
*/
public static final int PRECEDENCE_OR = PRECEDENCE_ADDITION - 400;
/**
* This is the threshold used to consider {@code false} values false, it has a default value
* of {@value}
*/
public static final double BOOLEAN_THRESHOLD = 1.0E-12;
/**
* The set of allowed operator chars
*/
private static final char[] ALLOWED_OPERATOR_CHARS = {
'+', '-', '*', '/', '%',
'^', '!', '#', '§', '$',
'&', ';', ':', '~', '<',
'>', '|', '=', '¬'
};
private final int numOperands;
private final boolean leftAssociative;
private final String symbol;
private final int precedence;
/**
* Create a new operator for use in expressions
* @param symbol the symbol of the operator
* @param numberOfOperands the number of operands the operator takes (1 or 2)
* @param leftAssociative set to true if the operator is left associative, false if it is right
* associative
* @param precedence the precedence value of the operator
*/
public Operator(String symbol, int numberOfOperands, boolean leftAssociative,
int precedence) {
super();
this.numOperands = numberOfOperands;
this.leftAssociative = leftAssociative;
this.symbol = symbol;
this.precedence = precedence;
}
/**
* Check if a character is an allowed operator char
* @param ch the char to check
* @return true if the char is allowed an operator symbol, false otherwise
*/
public static boolean isAllowedOperatorChar(char ch) {
for (char allowed: ALLOWED_OPERATOR_CHARS) {
if (ch == allowed) {
return true;
}
}
return false;
}
/**
* Check if the operator is left associative
* @return true os the operator is left associative, false otherwise
*/
public boolean isLeftAssociative() {
return leftAssociative;
}
/**
* Check the precedence value for the operator
* @return the precedence value
*/
public int getPrecedence() {
return precedence;
}
/**
* Apply the operation on the given operands
* @param args the operands for the operation
* @return the calculated result of the operation
*/
public abstract double apply(double ... args);
/**
* Get the operator symbol
* @return the symbol
*/
public String getSymbol() {
return symbol;
}
/**
* Get the number of operands
* @return the number of operands
*/
public int getNumOperands() {
return numOperands;
}
}