Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/*
* Copyright 2012 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package org.apache.felix.gogo.runtime;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
/**
* Enhanced to provide assignment operators and variables from a map, comparison operators, string operations and more.
*/
/**
*
EvalEx - Java Expression Evaluator
*
*
Introduction
* EvalEx is a handy expression evaluator for Java, that allows to evaluate simple mathematical and boolean expressions.
*
* Key Features:
*
*
Uses BigDecimal for calculation and result
*
Single class implementation, very compact
*
No dependencies to external libraries
*
Precision and rounding mode can be set
*
Supports variables
*
Standard boolean and mathematical operators
*
Standard basic mathematical and boolean functions
*
Custom functions and operators can be added at runtime
*
*
*
Examples
*
* BigDecimal result = null;
*
* Expression expression = new Expression("1+1/3");
* result = expression.eval():
* expression.setPrecision(2);
* result = expression.eval():
*
* result = new Expression("(3.4 + -4.1)/2").eval();
*
* result = new Expression("SQRT(a^2 + b^2").with("a","2.4").and("b","9.253").eval();
*
* BigDecimal a = new BigDecimal("2.4");
* BigDecimal b = new BigDecimal("9.235");
* result = new Expression("SQRT(a^2 + b^2").with("a",a).and("b",b).eval();
*
* result = new Expression("2.4/PI").setPrecision(128).setRoundingMode(RoundingMode.UP).eval();
*
* result = new Expression("random() > 0.5").eval();
*
* result = new Expression("not(x < 7 || sqrt(max(x,9)) <= 3))").with("x","22.9").eval();
*
*
*
Supported Operators
*
*
Mathematical Operators
*
Operator
Description
*
+
Additive operator
*
-
Subtraction operator
*
*
Multiplication operator
*
/
Division operator
*
%
Remainder operator (Modulo)
*
^
Power operator
*
*
*
*
Boolean Operators*
*
Operator
Description
*
=
Equals
*
==
Equals
*
!=
Not equals
*
<>
Not equals
*
<
Less than
*
<=
Less than or equal to
*
>
Greater than
*
>=
Greater than or equal to
*
&&
Boolean and
*
||
Boolean or
*
* *Boolean operators result always in a BigDecimal value of 1 or 0 (zero). Any non-zero value is treated as a _true_ value. Boolean _not_ is implemented by a function.
*
*
Supported Functions
*
*
Function*
Description
*
NOT(expression)
Boolean negation, 1 (means true) if the expression is not zero
*
IF(condition,value_if_true,value_if_false)
Returns one value if the condition evaluates to true or the other if it evaluates to false
*
RANDOM()
Produces a random number between 0 and 1
*
MIN(e1,e2)
Returns the smaller of both expressions
*
MAX(e1,e2)
Returns the bigger of both expressions
*
ABS(expression)
Returns the absolute (non-negative) value of the expression
*
ROUND(expression,precision)
Rounds a value to a certain number of digits, uses the current rounding mode
*
FLOOR(expression)
Rounds the value down to the nearest integer
*
CEILING(expression)
Rounds the value up to the nearest integer
*
LOG(expression)
Returns the natural logarithm (base e) of an expression
*
SQRT(expression)
Returns the square root of an expression
*
SIN(expression)
Returns the trigonometric sine of an angle (in degrees)
*
COS(expression)
Returns the trigonometric cosine of an angle (in degrees)
*
TAN(expression)
Returns the trigonometric tangens of an angle (in degrees)
*
SINH(expression)
Returns the hyperbolic sine of a value
*
COSH(expression)
Returns the hyperbolic cosine of a value
*
TANH(expression)
Returns the hyperbolic tangens of a value
*
RAD(expression)
Converts an angle measured in degrees to an approximately equivalent angle measured in radians
*
DEG(expression)
Converts an angle measured in radians to an approximately equivalent angle measured in degrees
*
* *Functions names are case insensitive.
*
*
Supported Constants
*
*
Constant
Description
*
PI
The value of PI, exact to 100 digits
*
TRUE
The value one
*
FALSE
The value zero
*
*
*
Add Custom Operators
*
* Custom operators can be added easily, simply create an instance of `Expression.Operator` and add it to the expression.
* Parameters are the operator string, its precedence and if it is left associative. The operators `eval()` method will be called with the BigDecimal values of the operands.
* All existing operators can also be overridden.
*
* For example, add an operator `x >> n`, that moves the decimal point of _x_ _n_ digits to the right:
*
*
*
* Adding custom functions is as easy as adding custom operators. Create an instance of `Expression.Function`and add it to the expression.
* Parameters are the function name and the count of required parameters. The functions `eval()` method will be called with a list of the BigDecimal parameters.
* All existing functions can also be overridden.
*
* For example, add a function `average(a,b,c)`, that will calculate the average value of a, b and c:
*
*
* The software is licensed under the MIT Open Source license (see LICENSE file).
*
*
*
The *power of* operator (^) implementation was copied from [Stack Overflow](http://stackoverflow.com/questions/3579779/how-to-do-a-fractional-power-on-bigdecimal-in-java) Thanks to Gene Marin
*
The SQRT() function implementation was taken from the book [The Java Programmers Guide To numerical Computing](http://www.amazon.de/Java-Number-Cruncher-Programmers-Numerical/dp/0130460419) (Ronald Mak, 2002)
*
*
*@author Udo Klimaschewski (http://about.me/udo.klimaschewski)
*/
public class Expression {
/**
* Definition of PI as a constant, can be used in expressions as variable.
*/
public static final BigDecimal PI = new BigDecimal(
"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679");
/**
* The {@link MathContext} to use for calculations.
*/
private MathContext mc = MathContext.DECIMAL32;
/**
* The original infix expression.
*/
private String expression = null;
/**
* The cached RPN (Reverse Polish Notation) of the expression.
*/
private List rpn = null;
/**
* All defined operators with name and implementation.
*/
private Map operators = new HashMap<>();
/**
* All defined functions with name and implementation.
*/
private Map functions = new HashMap<>();
/**
* All defined variables with name and value.
*/
private Map constants = new HashMap<>();
/**
* What character to use for decimal separators.
*/
private final char decimalSeparator = '.';
/**
* What character to use for minus sign (negative values).
*/
private final char minusSign = '-';
/**
* The expression evaluators exception class.
*/
public class ExpressionException extends RuntimeException {
private static final long serialVersionUID = 1118142866870779047L;
public ExpressionException(String message) {
super(message);
}
}
interface Token {
}
public class Constant implements Token {
private final Object value;
public Constant(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
}
public class Variable implements Token {
private final String name;
public Variable(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
public class LeftParen implements Token {
@Override
public String toString() {
return "(";
}
}
public class Comma implements Token {
}
/**
* Abstract definition of a supported expression function. A function is
* defined by a name, the number of parameters and the actual processing
* implementation.
*/
public abstract class Function implements Token {
/**
* Name of this function.
*/
private String name;
/**
* Number of parameters expected for this function.
*/
private int numParams;
/**
* Creates a new function with given name and parameter count.
*
* @param name
* The name of the function.
* @param numParams
* The number of parameters for this function.
*/
public Function(String name, int numParams) {
this.name = name.toUpperCase();
this.numParams = numParams;
}
public String getName() {
return name;
}
public int getNumParams() {
return numParams;
}
public BigDecimal eval(Map variables, List