Как стать автором
Обновить

Пишем графический ASCII-калькулятор с помощью стандартной библиотеки Си

Уровень сложностиСложный
Время на прочтение17 мин
Количество просмотров14K
Всего голосов 77: ↑76 и ↓1+75
Комментарии25

Комментарии 25

ЗакрепленныеЗакреплённые комментарии

Привет, я оригинальный автор. Я рада слышать, что статья вам понравилась! Очень приятно осознавать, что мою статью прочитал человек, имеющий опыт работы с программным обеспечением. Я слышал об упомянутой вами программе самонабора, думаю, это очень интересная задача для программы на языке C!

Похвально! Неважно, пока, что не все точно.

Я старый, начинал с минск32 .

Сегодня у меня маленькая фирма в Новосибирске-встроенное ПО.

Нужна была прога, которая делает любую прогу, написанную на любом, алгоритмически полном языке(это все современные языки, в том числе и старые), которая печатает сама себя-один7 в один.

на спектрум-бейсике подойдет?

10 LIST

RUN

Привет, я оригинальный автор. Я рада слышать, что статья вам понравилась! Очень приятно осознавать, что мою статью прочитал человек, имеющий опыт работы с программным обеспечением. Я слышал об упомянутой вами программе самонабора, думаю, это очень интересная задача для программы на языке C!

Спасибо за крутую статью! Она очень ценная.

Очень важно отметить, что поскольку эта программа написана на Си (или, говоря точнее, на компилируемом языке программирования), то, когда дело доходит до использования чисел с плавающей запятой, возникают присущие таким языкам неточности.

О каких неточностях идет речь? Почему эти неточности присущи только си и компилируемым языкам? В каких языках таких неточностей нету?

Видимо, автор оригинала недостаточно осведомлен о том, как реализуются операции с плавающей запятой в принципе. Думаю, можно списать это на то, что он еще студент.

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

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

@Bright_Translateпредоставил альтернативную реализацию алгоритма интеграции, которая уменьшает количество ошибок. Я применю этот и другие отзывы, когда вернусь к этой программе позже.

Возможно, обратная польская запись и позволяет вычислять значения выражений, но она значительно менее удобна, чем представление выражения в виде синтаксического дерева. Даже не вдаваясь в подробности, можно заметить в тексте фунции для вычисления значения выражения многочисленные сообщения об ошибках ( throw_error("invalid operation")), которые по сути являются ошибками синтаксиса. Конечно же, анализ синтаксической правильности выражения должен быть отделен от собственно вычисления его значения, для вычисления следует использовать выражение, уже точно являющееся синтаксически правильным. Тогда ошибки при вычислении могут быть только семантическим (вроде деления на 0), и не будет выполняться куча лишней работы. Синтаксическое дерево является намного более удобным промежуточным представлением для выражения. Кстати, и дифференцирование дерева намного легче выполнить в аналитическом виде, т.е. получив в результате снова дерево, а не числовое значение производной в точке (для функций, чуть более сложных, чем X^2, вычисление производной прямо по определению будет настоящим кошмаром)

Дерево, может, и удобнее, но явно проигрывает по скорости. Например, дерево придется обходить рекурсивно. А если пытаться оптимизировать вычисление, то все равно придем либо к ОПЗ, либо к чему-то среднему между AST и ОПЗ.

А вот что касается отсутствия лишних проверок на этапе вычисления это идея хорошая. Правда, на сколько мне известно, правильная реализация алгоритма предполагает все проверки на этапе построения обратной польской записи.

Дерево, может, и удобнее, но явно проигрывает по скорости

Это же калькулятор ;) Не удастся руками ввести выражение, на котором скорость алгоритма будет как-то заметна.

Это же калькулятор ;) Не удастся руками ввести выражение, на котором скорость алгоритма будет как-то заметна.

Эээ, нет, для построения графика нужно будет множество раз вычислять значение функции с разными аргументами

O(N*M) как было так и осталось.

Дерево, может, и удобнее, но явно проигрывает по скорости

Из представления в виде дерева очень легко получить обратную польскую запись (один раз, при помощи обратного обхода Left-Right-Node),и использовать ее для многократных вычислений. Ну, и я не уверен, что вычисления непосредственно по дереву будут сильно медленнее из-за рекурсии, но спорить не буду. По крайней мере, в своей системке, описанной здесь, я пользовался именно деревьями, а функции там приходится вычислять ну очень много раз (для численного решения диффуравнений), работает оно достаточно быстро

Аааа. Если предварительно построить эту обратную польскую запись, то да. Просто я подумал, что Вы предлагаете с деревом работать и на этапе вычисления.

Здравствуйте, спасибо, что прочитали статью! Я ценю ваши отзывы, они невероятно точны, мой выбор реализовать обратную польскую запись был ошибкой в ретроспективе. Хотя я решил использовать обратную польскую нотацию, более современные калькуляторы реализуют математические выражения с использованием синтаксического дерева. Многие решения и описания, приведенные в этой статье, являются побочным продуктом моего относительного отсутствия знаний в области программирования в старшей школе. С тех пор я многое узнал о том, как более эффективно реализовать что-то подобное. Возможно, когда-нибудь я вернусь к реализации calculator.c и улучшу его!

На Фокале график более практичнее выводится - со значениями Х:

Y = ?

Экраном до этого:

Имелось в виду .что на графике значения Х видны, а Y - не видны совсем. Таблица на другом листе распечатки - так себе наглядность.

Для Электроника-60 ( https://habr.com/ru/articles/678042/ ), Электроника-100-25 ( https://habr.com/ru/articles/692420/ ) это неплохое достижение.

Спасибо за прочтение статьи! Вот с чем я столкнулся при разработке своего калькулятора. Причина, по которой я решил сделать свой дисплей менее практичным, заключается в том, что я хотел подчеркнуть красоту ASCII, а не функциональность графического калькулятора. По этой причине я пропустил явные значения x и вместо этого решил выполнить сопоставление исключительно для отображения функции в ASCII. Хотя, возможно, если бы я сегодня вернулся в программу, я бы сделал стилизованное отображение индексов x и y, при этом y= отображался для каждой строки в левой части дисплея, а x= отображался вертикально внизу экрана.

Кстати, программа gnuplot умеет из коробки выводить график в консоль. Вам нужно всего лишь добавить:

set terminal dumb

Подробнее в моей статье Gnuplot. Пакуем выходной svg — в один файл

привет! слушай я с тобой хотел обсудить твой старый проект который был сделан 2 года назад, просто я не понял несколько вещей и хотел бы уточнить у тебя, как с тобой можно связаться?

Это же переводчик...

Зарегистрируйтесь на Хабре, чтобы оставить комментарий