I always appreciate coding in standard C++. There's something elegant about working with a language that's both powerful and standardized, where you can write portable code that runs anywhere.
Desktop Calculator is an application I've developed in standard C++, based on the calculator example (6.1) from "The C++ Programming Language", Third Edition by Bjarne Stroustrup. If you've read the book, you know it's one of the most comprehensive examples in the text, demonstrating how to build a complete, interactive program with proper error handling and architecture.
This implementation is released as GPL software, so you're free to use it, modify it, and learn from it.
What It Does
Desktop Calculator is a command-line expression evaluator that can:
- Evaluate mathematical expressions: Handle standard arithmetic operations (+, -, *, /)
- Exponentiation: Use the
^operator for powers (e.g.,2^8= 256) - Respect operator precedence: Follows proper mathematical order of operations
- Support parentheses: Group expressions with nested parentheses
- Handle variables: Assign values to named variables and use them in expressions
- Pre-defined constants:
piandeare built-in - Trigonometric functions:
sin(),cos(),tan() - Mathematical functions:
exp()(exponential),log()(natural logarithm) - Provide interactive mode: Enter expressions one at a time and see immediate results
- Report errors gracefully: Clear error messages without crashing
Example Usage
Here's what using the calculator looks like:
DC: Desk Calculator
press ctrl+Z to quit
2 + 3 * 4
14
(2 + 3) * 4
20
radius = 5
5
area = pi * radius ^ 2
78.5398
circumference = 2 * pi * radius
31.4159
sin(pi / 2)
1
log(e)
1
2 ^ 8
256
Note: Press Ctrl+Z (Windows) or Ctrl+D (Unix/Linux) followed by Enter to exit.
The Stroustrup Example
The calculator example in Stroustrup's book is a masterclass in C++ design. It demonstrates:
- Lexical analysis – Breaking input into tokens
- Parsing – Building an expression tree using recursive descent
- Evaluation – Computing results from the parsed tree
- Error handling – Gracefully managing invalid input
- Symbol table – Storing and retrieving variables
- Interactive I/O – Reading user input in a loop
My implementation follows this architecture closely, with some enhancements and personal touches.
Architecture Overview
The calculator is structured in several key components:
1. Token Stream
A Token_stream class handles input tokenization, breaking the input string into meaningful pieces:
- Numbers (e.g.,
42,3.14) - Operators (e.g.,
+,-,*,/) - Parentheses (
(,)) - Variable names (e.g.,
x,radius) - Assignment operator (
=)
2. Expression Parser
The parser uses recursive descent to handle operator precedence:
expression → term ('+' term | '-' term)*
term → primary ('*' primary | '/' primary | '%' primary)*
primary → number | variable | '(' expression ')' | '-' primary
This grammar ensures that multiplication and division have higher precedence than addition and subtraction, just like in mathematics.
3. Symbol Table
Variables are stored in a symbol table (using a C++ map), allowing you to:
x = 5
y = 10
result = x + y // result is 15
4. Error Recovery
When an error occurs, the calculator:
- Displays a clear error message
- Cleans up its internal state
- Continues running (doesn't crash)
- Prompts for the next expression
Key Features
Pre-defined Constants
The calculator includes mathematical constants:
pi
3.14159
e
2.71828
Variable Assignment
You can assign values to variables and reuse them:
width = 10
10
height = 20
20
area = width * height
200
Mathematical Functions
Built-in support for trigonometric and exponential functions:
sin(pi / 2)
1
cos(0)
1
tan(pi / 4)
0.707107
exp(1)
2.71828
log(e)
1
Exponentiation
Use the ^ operator for powers:
2 ^ 8
256
radius = 3
3
volume = (4.0 / 3.0) * pi * radius ^ 3
113.097
Expression Evaluation
Complex nested expressions work as expected:
((5 + 3) * 2 - 4) / 3
4
Error Handling
Invalid input produces helpful error messages:
5 + * 3
Error: primary expected
5 / 0
Error: divide by 0
The calculator tracks the number of errors and continues running even after encountering problems, making it resilient for interactive use.
The Code
Here's the complete implementation:
View the code on Gist.
The code is well-commented and follows the structure from Stroustrup's book, making it easy to understand and modify.
Building and Running
Requirements
- A C++ compiler supporting C++03 or later (GCC, Visual C++, etc.)
- Standard C++ library (included with most compilers)
Compilation
Using GCC (Linux/Mac)
g++ -o calculator calculator.cpp -std=c++03
./calculator
Using Visual C++ (Windows)
cl calculator.cpp
calculator.exe
Using Dev-C++ (Windows)
- Open the
.cppfile in Dev-C++ - Click Compile & Run (F9)
Running
Simply execute the compiled binary:
./calculator
Or on Windows:
calculator.exe
What I Learned
Building this calculator taught me several important C++ concepts:
1. Separation of Concerns
The calculator cleanly separates:
- Input handling (tokenization)
- Logic (parsing and evaluation)
- Data storage (symbol table)
- Error handling
Each component has a clear responsibility.
2. Recursive Descent Parsing
This technique is elegant and powerful. Once you understand the grammar, the code practically writes itself:
double expression() {
double left = term();
while (true) {
if (ts.get().kind == '+') {
left += term();
} else if (ts.get().kind == '-') {
left -= term();
} else {
ts.putback();
return left;
}
}
}
3. Error Recovery
Rather than crashing on bad input, the calculator recovers and continues. This requires careful state management and cleanup.
4. Interactive I/O
Building a read-eval-print loop (REPL) in C++ teaches you about:
- Stream handling
- Input validation
- User experience design
Possible Enhancements
This implementation already includes trigonometric functions (sin, cos, tan), exponential functions (exp, log), and constants (pi, e). But there's still room for more features:
Short-term Enhancements
- More functions: Add
sqrt,abs,ceil,floor,asin,acos,atan - More constants: Add
phi(golden ratio),tau(2π) - History: Allow recalling previous results with up/down arrows
- Improved help: More detailed built-in documentation
Medium-term Enhancements
- Expression history: Up/down arrow to recall previous expressions
- Save/load: Persist variables between sessions
- Script mode: Read expressions from a file
- Better error messages: Show where in the input the error occurred
Long-term Enhancements
- GUI version: Add a graphical interface
- Complex numbers: Support imaginary and complex arithmetic
- Matrix operations: Add vector and matrix support
- Programming constructs: Add loops, conditionals, functions
Why Standard C++?
I chose to stick with standard C++ (no platform-specific features) because:
- Portability: Runs on Windows, Linux, Mac without changes
- Learning: Focus on C++ itself, not platform APIs
- Simplicity: No external dependencies to manage
- Longevity: Standard C++ code ages well
Conclusion
This desktop calculator is a great example of how a relatively small C++ program can demonstrate important programming concepts:
- Parsing and evaluation
- Recursive algorithms
- Error handling
- State management
- Object-oriented design
If you're learning C++, I highly recommend working through the calculator example in Stroustrup's book. It's challenging but rewarding, and you'll come away with a deeper understanding of how to structure C++ programs.
The complete source code is available in the Gist above. Feel free to use it, modify it, and learn from it. That's why it's GPL licensed!
Happy calculating! Last modified: 2026-01-15 WordPress ID: 118
One reply on “Desktop Calculator”
Good for people to know.