<<Previous | ToC
| Next >>
For a simple 4-function calculator we can do it as a simple loop:
while (true) {You should be able to write this whole program without any help, if you use the Zystem input methods you already know about. Try it now, before reading any farther.
/// a. display the current result (initially =0)
/// b. accept a command letter:
/// c. if 'q' quit
/// d. if 'c' clear
/// e. accept a value
/// f. if command is '+' add
/// g. else if '-' subtract
/// h. else if '*' multiply
/// i. else if '/' divide
/// j. otherwise print error message
} // end of main loop
What data type did you choose for your display value? If you chose "int" what happens when you input or calculate fractional numbers? Java has two data types that work with non-integer numbers, float and double, but nobody uses float any more, it was initially designed for computer hardware with limited memory and/or that ran double width numbers slower than single. The computer in your pocket (it's called a "smart phone") has a thousand times more computer memory than all the first-generation (model 704) super-computers IBM ever made put together, so that's no longer a problem. Most of the math hardware is "pipelined" so the extra time it takes to calculate the wider result is overlapped by other calculations and does not slow anything down most of the time. Because float and double are different internal formats, the programmers got lazy and programmed everything in double, so the hardware designers no longer do the arithmetic in the shorter format, they just convert everything to double, do the math, then convert the result back to float (if that's what you want).
Bottom line: you probably want to use double as the data type whenever your data could extend past a few million (seven decimal digits, or nine if integer) or involve fractions, like for your result and input values in this calculator. That almost never happens in the programs I write, so I mostly use integers for everything. One consequence is that I have no "safe" input routines ready for you to use, you must write your own. Like taking your vitamins, it builds strong healthy bones (in your code ;-)
You could build your calculator in the same Hello class we have been using all along, but I think you are ready to start making your own Java classes. This first one is easy: inside the BlueJ dashboard (the "StartHere" window with the yellow rectangles) right-click the blank space behind those rectangles, or else pull down the Edit menu, and choose "New Class". In the dialog that pops up, give it your class name, like "Calculator" (it must start with a capital letter), verify that it will be making a Java class (later versions of BlueJ have several irrelevant options) and hit OK. Then double-click the new yellow rectangle with your class name.
What BlueJ gives you is a green box outlining the class, with two yellow boxes for methods. I deleted both yellow boxes and in their place (in the white space inside the green box) made a single
public static void main() {} // end of main
Just like in Hello. Notice that it made a new yellow box for you.
This is where your calculator code will go, in the white space inside that
yellow box. You will declare your variables on the first few lines there,
then put in our -- I mean your -- stub while loop and save it
and make sure it compiles. You need to declare a char variable
-- I called mine "optor" (short for "operator") but you can call
yours anything you like, just when I talk about optor, you substitute
your variable name.
OK, let's work on line (b), getting the operator input, for this first cut using Zystem.ReadLetter():
/// b. accept a command letter:
optor = Zystem.ReadLetter();
/// c. if 'q' quit
if (optor == 'q') return;
/// d. if 'c' clear
if (optor == 'c') {
/// clear your result variable
continue;} // back to the top of the loop
The user could type pretty much anything, and you (smart programmer
that you are becoming) need to cope with it and do something reasonable
and not too rude. Let's validate it:
if (optor != '+') if (optor != '-')
if (optor != '*') if (optor != '/') {
if (optor > ' ') // just ignore white space
System.out.println("Please type an operator: + - * / c q");
continue;}
As I said above, we will start by using integer input, my Zystem.ReadInt(),
reading it into either an int variable or a double. Let's
start with int (that's the type of the variable on its declaration
line). I called mine inval, but this is your program, you decide.
Now to read our input value:
inval = Zystem.ReadInt();
Do you think you can do the rest? Try it. If you have trouble making
the calculation work, but it compiles, it will probably run, and you can
use the debugger to see what's going wrong. If it won't compile, you will
have those red bars in the margin and you can click the error count in
the corner for a message. Often only the first error message makes any
sense.
After you have it working, you can test whether it's working correctly. Notice that if you give it a fractional value like 12.34, it only sees what's before the decimal point. That's because Zystem.ReadInt() stops reading at the decimal point. We'll fix that shortly. However, if you give it +1234, and then /100, the calculation is in double (you did declare the result that way, right?) so that gets you a fractional result.
What happens if you change the input variable (inval) to be double also?. Do you see any difference? Java automatically promotes integers to double when used in mixed-mode (both integer and double in the same) calculations, so when you read Zystem.ReadInt() into a double variable, it also gets promoted. Otherwise, if you are using a double for your result value, the (still integer) input value gets promoted when you do the arithmetic operation. You need to understand this, because the data types of the values you are using sometimes makes a difference, and sometimes promotion fixes it for you (like today). You need to understand why. If it's still foggy, ask the instructor, that's what they are here for.
When I ran my version and gave it goofy inputs, it did unexpected things,
probably because BlueJ is filtering the keyboard input. But it worked OK
when I gave it an operator and a number (with or without a space between
them), followed by return ("Enter" on most keyboards). In the next lesson,
when you replace my Zystem class with Scanner, you will
need to type a space between the operator and its number.
By the way, did you try giving it "/ 0" (divide by zero)?
Next: Exceptions
<<Previous | ToC | Next >>
Revised: 2021 May 11