I know how to make and sell software online, and I can share my tips with you.
Email | Twitter | LinkedIn | Comics | All articles

A simple command line calculator

Posted 17 years ago
How many times have you needed to calculate something, for example the value of 0x398A3BB, so you pop up windows calculator to convert it? I did lots of times. The problem is I hate to use the mouse. It takes precious deciseconds away from software development time to remove my hands from the keyboard and use the mouse. That's why I created calc.exe. Its a simple command line calculator (and its also an example of recursive decent parsing).

Examples

C:>calc 5+5*5
30.000000

c:>calc 0x30
48.000000

c:>calc (123456 % 51)/12
3.000000
Steve Hanov makes a living working on Rhymebrain.com, rapt.ink, www.websequencediagrams.com, and Zwibbler.com. He lives in Waterloo, Canada.
Post comment
Your Email (Not displayed): Post comment
Notice: Any comment containing "http(s):" will be entirely discarded.

Real Name

Editing Password (Optional):

Choose an edit password if you want to be able to edit or delete your comment later.
edit
Matt
two years ago
RE: Yolo's request in the comments. I made some small changes in S.Hanov's excellent calc.c code that may meet your needs and use is almost daily (on Windows 10). A copy of that code is at: github.com/mccright/ccalc

Thank you again, Steve Hanov!

edit
yolo
three years ago
Can somebody fix the debug output and post it somewhere?

thx

edit
Smith
five years ago
0x30 isn't "0 times 30". For that you would input 0*30.
edit
ProDigit
five years ago
you can do the same in python.
edit
Code55
eleven years ago
Any ways to remove the debug output mentionned by Kosenkov?

"Apparently you've forgotten to remove debug output:

C:>calc 10*4

parse_expr()

parse_term()

parse_factor()

parse_num_op()

parse_rest_term()

parse_factor()

parse_num_op()

parse_rest_term()

parse_rest_expr()

40.000000

"

edit
A Kosenkov
twelve years ago
Apparently you've forgotten to remove debug output:

C:>calc 10*4

parse_expr()

parse_term()

parse_factor()

parse_num_op()

parse_rest_term()

parse_factor()

parse_num_op()

parse_rest_term()

parse_rest_expr()

40.000000

edit
Marc Lepage
14 years ago
If you install cygwin for a Unix-like environment on Windows (bash shell and all the basic tools) then you have more options. You can use the built in expr (expression) command as a simple calculator. Or write a simple script to use Google's calculator (perhaps via Lynx or curl).
edit
Mario
14 years ago
Or you could, you know use a "real operating system" and not have to re-invent UNIX poorly :D.
edit
Simon Sapin
14 years ago
The parser example is interesting, but for a command line calculator I use this: (in ~/.bashrc)

calc() {

python -c "from math import *; print $*"

}

Example:

$ calc pi - 3

0.14159265359

This, or one of the ipython shells I have lying around.

edit
smallbug 2
15 years ago
oops

it seems that the replacement i did have effect on A ^ 9 expression...

the replacement should be :

resolve_variable(val);

if ( match_char( '^' ) ){

val_t val2;

parse_num_op( &val2 );

val->d.fval = pow( val->d.fval, val2.d.fval );

parse_rest_num_op( val );

}

parse_rest_expr( val );

edit
Small bug in the code !
15 years ago
Your code does not take in count expression like :

myVariable + 1

This is due to a bug in the void parse_rest_var function !

The following code solve this problem and seems to not have boundary effect !

void parse_rest_var( val_t* val )

{

if ( match_char( '=' ) ) {

val_t vexp;

parse_expr( &vexp );

if ( vexp.type != TYPE_FLOAT ) {

printf("Error: Tried to assign non-number to %s.\n", val->d.variable );

longjmp( env, 1 );

}

printf("Assigned to %s: ", val->d.variable );

map_add( val->d.variable, vexp.d.fval );

*val = vexp;

} else {

// -----------------------replace

// parse_rest_num_op( val );

// -- by

resolve_variable(val);

parse_rest_expr( val );

// ------------------End of modif !

}

Does Android team with eccentric geeks? (comic)

Rules for Effective C++

The rules for safe C++ code are surprisingly controversial.

The strange man reading a novel in the meeting room

Why is a visitor reading a novel all week in the meeting room?

Keeping Abreast of Pornographic Research in Computer Science

Burgeoning numbers of Ph.D's and grad students are choosing to study pornography. Techniques for the analysis of "objectionable images" are gaining increased attention (and grant money) from governments and research institutions around the world, as well as Google. But what, exactly, does computer science have to do with porn? In the name of academic persuit, let's roll up our sleeves and plunge deeply into this often hidden area that lies between the covers of top-shelf research journals.

How QBASIC almost got me killed

The day arrived when my project was ready to be unleashed upon the world. I waited until the teacher was hovering nearby and then I started my application, running the FORMAT command on the network drive. Some classmates were watching the screen and she hurried over to see what all the fuss was about.

Is 2009 the year of Linux malware?

Is 2009 the year of the linux desktop malware? How long until we see headlines like, "Researchers find massive botnet based on linux 2.30"?

Throw away the keys: Easy, Minimal Perfect Hashing

Perfect hashing is a technique for building a hash table with no collisions in the minimum possible space. They are a easy to build with this simple python function.

Detecting C++ memory leaks

It's fairly simple to redefine malloc() and free() to your own functions, to track the file and line number of memory leaks.

Zwibbler: A simple drawing program using Javascript and Canvas

Now it's a commercial product, but Zwibbler was once a fun side-project, and here's some details on its implementation.

Finding the top K items in a list efficiently

Do you use sort() to find the top results? Here's a simple trick that will make your software run much faster.