Как-то взялся я писать программу. Ничего особенного, программа, как программа, база данных, интерфейс, стандартный учет стандартной информации. Да вот только было в ней и кое-что интересное. Некоторые поля должны были рассчитываться на основе других, причем заранее не известно, на каких именно и каким образом. Т.е. надо было писать редактор формул, в котором можно было бы указывать какие поля взять и что с ними делать. Соответственно, потом по этим формулам надо было рассчитывать новое значение и заносить в таблицу.
С первой частью справиться труда не составило, и часов через несколько редактор был готов. Пользователь брал поля, которые были основой для расчета, компоновал из них формулу, разделяя все скобками и знаками арифметических действий. Короче, все кто видел построитель выражений в Microsoft программах, поймет, что у меня получилось в итоге.
Ну все хорошо, формула есть, только как же теперь ее посчитать? Первой возникшей мыслью было то, что задача не нова, и наверняка кто-то где-то уже делал подобное. Поиск в Интернете принес некоторые результаты, но, честно говоря, огорчил меня тем, что все что я нашел было либо основной идейной линией, которая была и так понятна, либо это были готовые программы, типа строкового калькулятора.
Полезным оказался только один пример на Дельфи, в котором данная задача решалась, но во-первых, все равно надо было переписывать на VB, а во-вторых, там было все на столько сложно сделано, что удивительно, как это вообще работает.
По этому, было принято решение писать самостоятельно. И вот что из этого получилось.
Итак, что сбой представляет любая формула, с математическими функциями, возведениями в степень и скобками? Это последовательность действий, которые необходимо осуществить с элементами формулы, чтобы получить в итоге результат. Все действия имеют разный приоритет. Нам необходимо научить компьютер осуществлять эти действия.
Любая формула, сколько бы в ней элементов и операций не было, всегда упрощается до простой арифметики с четырьмя типами математических операций: +,-,/,*.
50+sin(1)*cos(0)/(450/(78+45)) рассчитывая последовательно выражения внутри скобок и функции получим:
50+0*1/3.65 - вот функция, упрощенная до простых арифметических операций.
Вывод: первое, что необходимо запрограммировать - "движок", который бы умел считать такие выражения с четырьмя простейшими арифметическими действиями.
Нам необходимо представить текстовую строку, которая не имеет никакой смысловой нагрузки для VB в таком виде, чтобы мы могли работать с элементами формулы как с отдельными самостоятельными элементами, т.е. цифрами и знаками арифметических выражений. Причем должна сохраняться связь между ними и порядок действий. Первый выход, который показался мне реальным - массив. Итак,
Во-первых: Статья была написана только в образовательных целях, поэтому просто скопировать текст и вставить в модуль не получится. Я намеренно изменил кое-что в коде, но если голова на месте, поняв принцип работы интерпретатора, исправите сами и все заработает.
Во-вторых: Это только движок, и формулы со скобками и функциями он не считает. Чтобы работать со скобками, необходимо последовательно интерпретировать выражения внутри скобок, заменять их в формуле полученным результатом, и, в итоге, интерпретировать упрощенное выражение. С функциями то же самое.
В-третьих: Подумайте сами, как это все заставить работать с отрицательными числами.