- Вычисление математического выражения в Java
- 2. exp4j
- 2.1. Добавление зависимости Maven
- 2.2. Оценка простых выражений
- 2.3. Использование переменных в выражениях
- 2.4. Вычисление выражений, содержащих математические функции
- 3. Явалюатор
- 3.1. Добавление зависимости Maven
- 3.2. Оценка простых выражений
- 3.3. Вычисление выражений, содержащих переменные
- 3.4. Вычисление выражений, содержащих математические функции
- 4. API сценариев Java
- 4.1. Получение экземпляра ScriptEngine
- 4.2. Оценка простых выражений
- 4.3. Вычисление выражений, содержащих переменные
- 5. Вывод
- IDEA: evaluate expression
- Java Math класс и его методы
- Вычисление значений тригонометрических функций
- Возведение в степень
- Извлечение корней
- Генерация случайных чисел
- Округление
- Заключение
Вычисление математического выражения в Java
В этом руководстве мы обсудим различные подходы к оценке математического выражения с использованием Java. Эта функция может пригодиться в проектах, где мы хотим оценить математические выражения, представленные в строковом формате.
Для начала мы обсудим несколько сторонних библиотек и их использование. Далее мы увидим, как мы можем использовать встроенный API сценариев Java для решения этой задачи.
2. exp4j
exp4j — это библиотека с открытым исходным кодом, которую можно использовать для вычисления математических выражений и функций. Библиотека реализует алгоритм Дейкстры Shunting Yard Algorithm, метод разбора математических выражений, заданных в инфиксной нотации .
Помимо использования стандартных операторов и функций, exp4j позволяет нам создавать собственные операторы и функции.
2.1. Добавление зависимости Maven
Чтобы использовать exp4j, нам нужно добавить зависимость Maven в наш проект:
dependency> groupId>net.objecthuntergroupId> artifactId>exp4jartifactId> version>0.4.8version> dependency>
2.2. Оценка простых выражений
Мы можем оценить простое математическое выражение, представленное в формате String :
@Test public void givenSimpleExpression_whenCallEvaluateMethod_thenSuccess() Expression expression = new ExpressionBuilder("3+2").build(); double result = expression.evaluate(); Assertions.assertEquals(5, result); >
В приведенном выше фрагменте кода мы сначала создаем экземпляр ExpressionBuilder . Затем мы присваиваем его ссылке Expression , которую используем для оценки нашего выражения.
2.3. Использование переменных в выражениях
Теперь, когда мы знаем, как вычислять простые выражения, давайте добавим в наше выражение несколько переменных:
@Test public void givenTwoVariables_whenCallEvaluateMethod_thenSuccess() Expression expression = new ExpressionBuilder("3x+2y") .variables("x", "y") .build() .setVariable("x", 2) .setVariable("y", 3); double result = expression.evaluate(); Assertions.assertEquals(12, result); >
В приведенном выше примере мы вводим две переменные, x и y, используя метод переменных . Мы можем добавить в выражение столько переменных, сколько нам нужно , используя этот метод. Как только мы объявили переменные, мы можем присвоить им значения, используя метод setVariable .
2.4. Вычисление выражений, содержащих математические функции
Давайте теперь посмотрим на краткий пример того, как мы можем оценить некоторые стандартные математические функции:
@Test public void givenMathFunctions_whenCallEvaluateMethod_thenSuccess() Expression expression = new ExpressionBuilder("sin(x)*sin(x)+cos(x)*cos(x)") .variables("x") .build() .setVariable("x", 0.5); double result = expression.evaluate(); Assertions.assertEquals(1, result); >
3. Явалюатор
Javaluator — еще одна независимая и легкая библиотека, доступная бесплатно. Как и exp4j, Javaluator также используется для вычисления инфиксных выражений .
3.1. Добавление зависимости Maven
Мы можем использовать следующую зависимость Maven для использования Javaluator в нашем проекте:
dependency> groupId>com.fathzergroupId> artifactId>javaluatorartifactId> version>3.0.3version> dependency>
3.2. Оценка простых выражений
Чтобы оценить выражения с помощью Javaluator, нам сначала нужно создать экземпляр DoubleEvaluator :
@Test public void givenExpression_whenCallEvaluateMethod_thenSuccess() String expression = "3+2"; DoubleEvaluator eval = new DoubleEvaluator(); Double result = eval.evaluate(expression); Assertions.assertEquals(5, result); >
3.3. Вычисление выражений, содержащих переменные
Для оценки выражений, содержащих переменные, мы используем StaticVariableSet :
@Test public void givenVariables_whenCallEvaluateMethod_thenSuccess() String expression = "3*x+2*y"; DoubleEvaluator eval = new DoubleEvaluator(); StaticVariableSetDouble> variables = new StaticVariableSetDouble>(); variables.set("x", 2.0); variables.set("y", 3.0); Double result = eval.evaluate(expression, variables); Assertions.assertEquals(12, result); >
Затем мы используем метод StaticVariableSet#set для присвоения значений переменным.
3.4. Вычисление выражений, содержащих математические функции
Мы также можем решать выражения, содержащие математические функции, используя библиотеку Javaluator:
@Test public void givenMathFunction_whenCallEvaluateMethod_thenSuccess() String expression = "sin(x)*sin(x)+cos(x)*cos(x)"; DoubleEvaluator eval = new DoubleEvaluator(); StaticVariableSetDouble> variables = new StaticVariableSetDouble>(); variables.set("x", 0.5); Double result = eval.evaluate(expression, variables); Assertions.assertEquals(1, result); >
4. API сценариев Java
Теперь, когда мы обсудили сторонние библиотеки, давайте теперь обсудим, как мы можем добиться этого с помощью встроенного API. Java уже поставляется с небольшим, но мощным API сценариев. Все классы и интерфейсы этого API находятся в пакете javax.script .
Он содержит интерфейсы ScriptEngineManager и ScriptEngine , которые позволяют нам оценивать JavaScript. До Java 8 Java поставлялась с движком Rhino . Однако, начиная с Java 8, Java поставляется с более новым и мощным движком Nashorn .
4.1. Получение экземпляра ScriptEngine
Чтобы создать ScriptEngine , нам сначала нужно создать экземпляр ScriptEngineManager . Получив экземпляр, нам нужно вызвать метод ScriptEngineManager#getEngineByName , чтобы получить ScriptEngine :
ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
Обратите внимание, что Nashorn — это движок JavaScript по умолчанию, который поставляется вместе с JDK.
4.2. Оценка простых выражений
Теперь мы можем использовать приведенный выше экземпляр scriptEngine для вызова метода ScriptEngine#eval :
String expression = "3+2"; Integer result = (Integer) scriptEngine.eval(expression); Assertions.assertEquals(5, result);
4.3. Вычисление выражений, содержащих переменные
Чтобы оценить выражения, содержащие переменные, нам нужно объявить и инициализировать переменные:
String expression = "x=2; y=3; 3*x+2*y;"; Double result = (Double) scriptEngine.eval(expression); Assertions.assertEquals(12, result);
Поскольку мы используем движок JavaScript, мы можем напрямую добавлять переменные в выражения, как мы это делаем в JavaScript .
**Примечание. JavaScript не имеет прямых методов для выполнения математических операций и требует доступа к объекту Math . Таким образом, мы не можем решать математические выражения с помощью Java Scripting API.
5. Вывод
В этой статье мы рассмотрели различные методы вычисления математических выражений с использованием Java.
Как всегда, полный код этого примера доступен на GitHub .
- 1. Обзор
- 2. exp4j
- 2.1. Добавление зависимости Maven
- 2.2. Оценка простых выражений
- 2.3. Использование переменных в выражениях
- 2.4. Вычисление выражений, содержащих математические функции
- 3.1. Добавление зависимости Maven
- 3.2. Оценка простых выражений
- 3.3. Вычисление выражений, содержащих переменные
- 3.4. Вычисление выражений, содержащих математические функции
- 4.1. Получение экземпляра ScriptEngine
- 4.2. Оценка простых выражений
- 4.3. Вычисление выражений, содержащих переменные
IDEA: evaluate expression
— Кроме Watches есть еще мощный инструмент – это EvaluateExpression.
Кликаешь на переменной в коде правой кнопкой и выбираешь в меню EvaluateExpression. Ну, или просто жмешь Alt+F8.
Тогда открывается волшебное окно, где можно вычислить значение любого выражения:
Но, как я сказала, там можно написать любое выражение:
Все эти переменные можно посмотреть, как можно посмотреть и все, на что они ссылаются и т.д.
— Думаю это очень удобная штука для больших программ.
А хочешь выполнить произвольный код прямо во время работы программы, работая с данными этой программы?
— Конечно. Для этого есть кнопка – CodeFragmentMode . Нажимай ее и переключайся в режим, где можно вводить целые «фрагменты кода», состоящие из нескольких строк.
Я тут: использовала переменную sum5 , вызвала метод sum() , объявила несколько переменны х, указала им значения и вычислила результат всего этого.
— Как по мне – это очень круто. Особенно, что можно делать разные действия с текущими переменными, такими как sum5, sum7. Ну, а то, что можно вызывать методы и создавать переменные – так это вообще делает мои возможности практически безграничными.
— Ага. Это очень круто. Ты можешь выполнить код, вывести в нем что-то в консоль и оно выведется в консоль! Это полноценный рабочий код. Без всяких ограничений.
— Спасибо, Элли. Это были несколько очень познавательных, и я не побоюсь этого слова, одни из самых полезных уроков за все время.
Java Math класс и его методы
В данной статье мы проведем краткий обзор класса Math в Java. Поговорим о методах данного класса и о том, как их использовать. Класс Math располагается в пакете java.lang и предоставляет набор статических методов для осуществления ряда различных математических вычислений. Ниже приведены примеры вычислений, для которых класс Math может оказаться полезным:
- Вычисление абсолютных значений (значений по модулю)
- Вычисление значений тригонометрических функций (синусов, косинусов и т.д.)
- Возведение в различные степени
- Извлечение корней различных степеней
- Генерация случайных чисел
- Округления
- И пр.
Ниже мы попробуем рассмотреть как класс Java Math помогает решать задачи, перечисленные выше.Начнем разбор класса с методов, которые позволяют вычислить значение по модулю. За это отвечает метод abs. Данный метод перегружен и в классе Math имеются следующие его различия:
- static double abs(double a)
- static float abs(float a)
- static int abs(int a)
- static long abs(long a)
Пример использования:
public static void main(String[] args) < System.out.println(Math.abs(-1)); // 1 System.out.println(Math.abs(-21.8d)); // 21.8 System.out.println(Math.abs(4532L)); // 4532 System.out.println(Math.abs(5.341f)); // 5.341 >
Вычисление значений тригонометрических функций
- static double sin(double a)
- static double cos(double a)
- static double tan(double a)
- static double asin(double a)
- static double acos(double a)
- static double atan(double a)
- static double toDegrees(double angrad)
- static double toRadians(double angdeg)
public static void main(String[] args)
0.0 0.49999999999999994 1.0 1.0 0.8660254037844387 6.123233995736766E-17
Что не совсем соответствует таблицам синусов и косинусов, отчасти благодаря погрешностям при переводе из градусов в радианы.
Возведение в степень
Для возведения числа в степень класс Math предоставляет метод pow, который имеет следующую сигнатуру:
static double pow(double a, double b)
public static void main(String[] args) < System.out.println(Math.pow(1,2)); // 1.0 System.out.println(Math.pow(2,2)); // 4.0 System.out.println(Math.pow(3,2)); // 9.0 System.out.println(Math.pow(4,2)); // 16.0 System.out.println(Math.pow(5,2)); // 25.0 System.out.println(Math.pow(1,3)); // 1.0 System.out.println(Math.pow(2,3)); // 8.0 System.out.println(Math.pow(3,3)); // 27.0 System.out.println(Math.pow(4,3)); // 64.0 System.out.println(Math.pow(5,3)); // 125.0 >
Извлечение корней
public static void main(String[] args) < System.out.println(Math.sqrt(4)); // 2.0 System.out.println(Math.sqrt(9)); // 3.0 System.out.println(Math.sqrt(16)); // 4.0 System.out.println(Math.cbrt(8)); // 2.0 System.out.println(Math.cbrt(27)); // 3.0 System.out.println(Math.cbrt(125)); // 5.0 >
Генерация случайных чисел
Для генерации случайных чисел класс Math предоставляет метод random. Данный метод генерирует случайное позитивное вещественное (double) число в промежутке от 0.0 до 1.0. Сигнатура метода имеет следующий вид:
public static double random()
public static void main(String[] args) < for (int i = 0; i < 5; i++) < System.out.println(Math.random()); >>
0.37057465028778513 0.2516253742011597 0.9315649439611121 0.6346725713527239 0.7442959932755443
С помощью небольших манипуляций, можно использовать метод random класса Math для получения целочисленных случайных чисел лежащих в определенном диапазоне. Приведем пример функции которая принимает два аргумента min и max и возвращает случайное целое число, которое лежит в промежутке от min (включительно) до max (включительно):
static int randomInARange(int min, int max)
public class MathExample < public static void main(String[] args) < // Карта, в которой мы будем хранить количество выпадений какого-то числа Mapmap = new TreeMap<>(); // За 10000 операций for (int i = 0; i < 10000; i++) < // Сгенерируем рандомное число от -10 включительно до 10 включительно final Integer randomNumber = randomInARange(-10, 10); if (!map.containsKey(randomNumber)) < // Если карта еще не содержит "выпавшего случайного числа" // Положим его в карту с кол-вом выпадений = 1 map.put(randomNumber, 1); >else < // Иначе, увеличим количество выпадений данного числа на 1 map.put(randomNumber, map.get(randomNumber) + 1); >> // Выведем на экран содержимое карты в формате ключ=[значение] for (Map.Entry entry : map.entrySet()) < System.out.println(String.format("%d=[%d]", entry.getKey(), entry.getValue())); >> static int randomInARange(int min, int max) < return (int) (Math.random() * ((max - min) + 1)) + min; >>
-10=[482] -9=[495] -8=[472] -7=[514] -6=[457] -5=[465] -4=[486] -3=[500] -2=[490] -1=[466] 0=[458] 1=[488] 2=[461] 3=[470] 4=[464] 5=[463] 6=[484] 7=[479] 8=[459] 9=[503] 10=[444] Process finished with exit code 0
Округление
- static long round(double a)
- static int round(float a)
- static double floor(double a)
- static double ceil(double a)
public static void main(String[] args) < System.out.println(Math.round(1.3)); // 1 System.out.println(Math.round(1.4)); // 1 System.out.println(Math.round(1.5)); // 2 System.out.println(Math.round(1.6)); // 2 System.out.println(Math.floor(1.3)); // 1.0 System.out.println(Math.floor(1.4)); // 1.0 System.out.println(Math.floor(1.5)); // 1.0 System.out.println(Math.floor(1.6)); // 1.0 System.out.println(Math.ceil(1.3)); // 2.0 System.out.println(Math.ceil(1.4)); // 2.0 System.out.println(Math.ceil(1.5)); // 2.0 System.out.println(Math.ceil(1.6)); // 2.0 >
Заключение
- Вычислять значения по модулю;
- Вычислять значения тригонометрических функций;
- Возводить числа в степень;
- Извлекать квадратный и кубический корни;
- Генерировать случайные числа;
- Округлять числа.