mitasov-ra / calc

RPN calculator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

calc

Калькулятор, работающий на Обратной польской нотации.

Основной класс - Expression. Он является неизменяемым и представляет скомпилированное арифметическое выражение. В выражении поддерживаются следующие операции и функции:

  • + -- сложение
  • -, -- вычитание
  • *, , , ×, -- умножение
  • /, ÷, -- деление
  • ^ -- возведение в степень
  • ! -- факториал
  • % -- перевод в проценты
  • , sqrt -- радикал (квадратный корень)
  • log -- логирифм по основанию 10
  • ln -- натуральный логарифм
  • exp -- экспонента
  • abs -- абсолютная величина
  • sgn -- сигнум
  • sin -- синус
  • cos -- косинус
  • tan, tg -- тангенс
  • cot, ctg -- котангенс
  • arcsin -- арксинус
  • arccos -- арккосинус
  • arctan, arctg -- арктангенс
  • arccot, arcctg -- арккотангенс
  • sinh, sh -- гиперболический синус
  • cosh, ch -- гиперболический косинус
  • tanh, th -- гиперболический тангенс
  • coth, cth -- гиперболический котангенс

Выражение может содержать в себе именованные константы. Грамматика констант и допустимые символы позаимствованы у языка Java, поэтому все символы, которые могут быть идентификаторами в Java, могут также быть константами в выражении. Допустимые имена констант:

a, b, c, const1
значение1, значение2, высота, ширина

Константы не могут иметь те же имена что и функции. Помимо этого, для выражения зарезервированы математические константы:

  • pi, π, 𝜋 -- число Пи;
  • e, 𝑒 -- экспонента.

Синтаксис арифметических выражений близок к класическому, но имеет некоторые улучшения. Символы пробела, переносов строки и табуляции используются как разделители операндов, если написать два операнда раздельно, это будет эквивалентно операции умножения. Кроме этого, десятичные дроби можно записывать, опуская ноль перед точкой. Так, следующие выражения полностью эквивалентны:

2a     <==> 2 a <==> 2 * a
sin pi <==> sin(pi)
√-4    <==> √(-4)
0.24   <==> .24
0.     <==> .0 <==> . <==> 0
(2a sin 3)(a b cos c) <==> (2*a*sin(3))*(a*b*cos(c))

Использование

Подключение:

import mitasov.calc.Expression;

Простой пример:

Expression e = new Expression("2+2"); //целые числа
double res1 = e.evaluate(); // == 4

e = new Expression("2.564 * 2"); //дробные
res = e.evaluate(); // == 5.128

e = new Expression("2,5 - 3", ',') //можно указать символ плавающей точки
res = e.evaluate(); // == -0.5

Пример использования констант

Expression e = new Expression("a+b"); // a и b будут иметь значения null

e.getConstants().put("a", 3);
e.getConstants().put("b", 4);

double res = e.evaluate(); // == 7
Получение списка констант:
Set<String> names = e.getConstants().names(); //набор имён констант из выражения
Set<Map.Entry<String, Double>> entries = e.getConstants().entrySet(); //набор пар имя=значение
Collection<Double> values = e.getConstants().values(); //коллекция значений


for (String name : names) { //пример итерации по именам
    System.out.println(name); //выведет имя
    System.out.println(e.getConstants().get(name)); //выведет значение
}

Обработка ошибок

Класс Expression при создании и вычислении выражения может бросить исключение ExpressionException. Определить, какая ошибка произошла, можно, вызвав метод ExpressionException#getCode(). Метод вернёт enum-элемент типа ExpressionException.Code. Коды ошибок бывают следующие:

Ошибки в ходе анализа (лексические и синтаксические)
  • INVALID_CHARACTER - неверный (неизвестный) символ;
  • WRONG_NUMBER - неверный формат числа;
  • OPERATOR_WITHOUT_OPERAND - не указан операнд для оператора (напр. "2+");
  • RPAREN_UNEXPECTED - неверное положение закрывающей скобки;
  • LPAREN_MISSING - не хватает открывающей скобки (закрывающая скобка без открывающей);
  • UNEXPECTED_END - неожиданный конец выражения;
Ошибки в ходе вычисления
  • SQRT_OF_NEG - квадратный корень из отрицательного числа;
  • FACT_OF_NEG - факториал отрицательного числа;
  • LOG_OF_NEG - логарифм отрицательного числа;
  • UNDEFINED_CONST - неопределённая константа (не указано значение);
  • DIV_BY_ZERO - деление на ноль;

Объект ExpressionException кроме сообщения и кода содержит информацию о позиции ошибочной подстроки и о её длине

try {
    Expression e = new Expression("26+*983"); // бросит исключение на символе '*'
} catch (ExpressionException e) {
    System.out.println(e.getCode());     // выведет OPERATOR_WITHOUT_OPERAND
    System.out.println(e.getMessage());  // выведет "Operator used without operand"
    System.out.println(e.getPosition()); // выведет 3
    System.out.println(e.getLength());   // выведет 1
    System.out.println(e.getEndPosition()); // то же что и сумма позиции и длины
}

При попытке вычислить выражение, не назначив константам значения, метод evaluate() будет выбрасывать ошибку с кодом UNDEFINED_CONST

В случаях деления на ноль или получения факториала отрицательного числа, метод evaluate() не будет выбрасывать исключение, а будет возвращать Infinite или NaN. Чтобы "включить" исключение, необходимо вызвать метод evaluateStrict():

try {
    Expression e = new Expression("10 / 0");
    double d = e.evaluate(); // бесконечность

    d = e.evaluateStrict();
} catch (ExpressionException e) {
    System.out.println(e.getCode()); // DIV_BY_ZERO
}

About

RPN calculator


Languages

Language:Java 100.0%