DIY Calculator

Posted: 11/22/2019 12:23:21 AM

From: Northern NJ, USA

Joined: 2/17/2012


The terminal calc is mostly done, here are some screenshots:

The above shows decimal mode.

The above shows hex float mode.

The above shows 32.32 hex float mode.

The above shows the stack / memory highlight and the function key highlight in different locations.

Most of my goals have been met!  Numeric base is a display mode rather than a functional mode, so you can switch all you like without affecting anything.  The stack depth is unlimited, but only the first 10 entries are displayed.  Memory has 10 just slots, all displayed.  There is a highlight you can move around the stacks via SHIFT and the arrow keys to select things for copying / deleting / storing / recalling.  There is a similar highlight for the function keys you move up and down with CTRL and the up / down arrow keys to select the function bank.  You can just type the functions in too, which is usually faster for me.  White space alone dups the last stack entry (or the thing with the highlight).  DEL alone deletes the last stack entry (or the thing with the highlight).  Previous operation and status is shown above the command line.  Four angle modes: radians, degrees, grads, fractional (0 to 1 for full circle, like binary SIN2, etc.).

- Kill trailing zeros in the hex float mode.
- Make the help file.
- File I/O?

[EDIT] Made the help file, typing "help" on the command line brings it up.  Moved all the hyperbolics to their own function bank.  Added "help" and "fix" to the last function bank.  There are amazingly few basic math functions even in a fairly advanced scientific calculator.  An undo of some sort would be helpful, not sure I want to go that far (HP often gives you a "last x" which is partially useful).

Posted: 11/22/2019 4:50:47 PM

From: Northern NJ, USA

Joined: 2/17/2012

Tangled Up In Blue

The green motif was a little too "restful" so I switched it to blue:

I really don't know what to do with the conflict between entering a negative number with the preceding '-' sign and using the '-' key to do subtraction immediately.  Right now I've got it so you have to enter white space after '+', '-', '*', and '/' to initiate the math function, which is awkward.  Not allowing direct negative number entry (entering numbers as non-negative and using the "chs" function) is how calculators get around this, perhaps I will end up doing the same.  But I don't really like either method.

Posted: 11/22/2019 6:35:58 PM

From: Theremin Motherland

Joined: 11/13/2005

How about 'ctrl'  +  '-'  ?

Posted: 11/22/2019 7:59:22 PM

From: Northern NJ, USA

Joined: 2/17/2012

"How about 'ctrl'  +  '-'  ?"  - ILYA

Excellent idea!  Unfortunately I get no key codes for CTRL+ or CTRL-.  And CTRL* and CTRL/ give the same key codes as * and /.  Same for SHIFT.  ALT gives the same key codes (for +-*/) as no ALT. This is all in the Linux console, not sure about MS, but I would like for it to be portable.

I had +-*/ assigned to a bank of the function keys, but it wasn't very intuitive nor easy to use.

So many OS / SW layers between me and the keys, all doing their own thing.

Tried the CHS solution and it kinda sucks.

It seems as though I could use a more robust command line parser feeding the tokenizer, sort of a mini assembler.  But even that won't solve the leading '-' problem.

Posted: 11/22/2019 10:57:18 PM

From: Northern NJ, USA

Joined: 2/17/2012

Linux Launcher

So the way to make shortcuts to executable files in Linux Mint is to right click on the desktop and select "Create new launcher here..." then open and edit it with a text editor.  If it's a console app you can set the size of the console, and if the app needs access to local files you can set the working directory.  Here is the launcher for my calculator:

[Desktop Entry]
Exec=gnome-terminal --geometry 80x20 -x  /home/demo/Documents/CPP/calc/_SRC_/calc

Works like a champ!  Note the explicit setting of the terminal dimensions via the "geometry" keyword.

[EDIT] Just edited things so that when single operand functions are performed stack[0] is first copied to memory[0].  Two operand functions also first copy stack[1] to memory[1].  So you can undo one level if things go pear shaped.

Posted: 11/25/2019 4:30:03 AM

From: Northern NJ, USA

Joined: 2/17/2012

Swapped Mem & Stack Columns

Rearranging things slightly. It's trivial I know, but the stack and input seem a bit more natural on the right, perhaps because the number pad on the keyboard is on the right?:

For me it's this aesthetic stuff at the end that often has the most payoff - simple to do but can really impact usability.

Posted: 12/7/2019 2:47:50 PM

From: Northern NJ, USA

Joined: 2/17/2012

Input Logic Done

Finally figured out input logic I can live with.  One trick was to intercept key strokes up-front and translate keys like '+' to mnemonics like "add" so that calling them back up via the command prompt history won't re-interpret them again.  This also keeps them from mixing back in with any number values on the same line.  So now I can type in a number and name an operation with a operation symbol key without having to separate the number and operation via white space.  Neither the last number nor the operation need to be on the stack to do their thing (though you can put them there if you want), thus saving a bunch of keystrokes, and thus behaving much like old HP calculators.  The biggest downside is you have to use the "chs" function to enter negative numbers, but you can use the '-' key to enter negative exponents as the logic is aware of input exponents in the various input modes.

Above is the current state of the calc.  I went ahead and moved all the trig functions over to the left.

I don't 100% like the way I've implemented floating point hex display - it should round to the display precision, kill trailing zeros, and automatically switch to / from exponential.  But I'm not completely sanguine with the way decimal float display is implemented in C++ either, as it's rather schizophrenic about what "fix" actually means, so it often rounds decimals when it should be switching to exponential to preserve the display of significant digits.  To me, "fix" should be all about significant digits, rather than decimal places.  But this is a fairly tough problem to solve in hex, and really tough in base 10.  (Why, oh why, did we "pick" base 10 for our arithmetic?  If I were king of the world I'd switch us all over to base 4 - kids learning their multiplication tables would thank me!  And you can "see" 4 of something at a glance without counting, not so with 10 of something.)

Posted: 12/12/2019 3:07:44 PM

From: Northern NJ, USA

Joined: 2/17/2012

Number Formats & Readability

I've been thinking about number formats a lot, and the subject is much more complicated than I imagined.  By formats, I mean the usual decimal, scientific, and engineering notations.  Much of this complexity is due to limitations of human perception and readability (other complexity is accurately converting the values to text).  Some insights:

1. Fixing the decimal digits for scientific notation actually sets the significant digits (to fix + 1) because there is always one digit to the left of the decimal place.  This unfortunately isn't the case for the other formats, so the use of fix isn't a general solution to control the display of significant digits.

2. Thousands separators (groups of 3 digits) employed to the left of the decimal place can dramatically improve the readability of numbers much larger than one.  But separators aren't generally employed to the right of the decimal place, which severely limits readability for numbers much less than one.

3. Too many thousands separators can also be confusing, and one is generally only interested in a "close enough" answer, so displaying only the significant digits necessary, along with a shift value (exponent) can dramatically improve readability.

4. Engineering notation is nice because it lets you use thousands prefixes directly (femto, pico, milli, kilo, mega, etc.).  But engineering notation forces a certain amount of "filler" zeros for certain values limited to a certain number of significant digits.  For example, "500,000,000" only has one significant digit, but in engineering notation it is displayed as "500E+6" which requires 3 digits (zero padding of 2).

Due to the reasons above, calculators and programming languages usually have a way to force the display of a certain format, as well as a "best fit" type format which selects the display format presumably somehow based on the human readability of the given value.  For C++ there is a "best fit" format for base 10 number display that works fairly well, but unfortunately no equivalent "best fit" format for hex display when the input value is a quad float (__float128).  It's this lack in C++ which has forced me to look into this issue much more deeply than I had initially intended to.


Trying to keeping the coding effort alive, though it's really slow going.  Yesterday made a class for the stack so it's easier to interact with via an index (the vector type is a kind of LIFO, but the indexing is reversed to how I label the stack indices).  Some basic stack manipulations are now directly handled by the class.  I also made command errors show up in a red font in the history, as well as other minor improvements.  So the whole thing is basically there and in good shape - except for the actual display of the numbers!


Alternative Scientific Notation Format?

Did "they" blow it when "they" came up with the scientific notation format?  I mean, why have anything significant to the left of the decimal place?  For example, the value "56.234" in scientific notation is "5.6234E+1" but wouldn't it be better for it to be "0.56234E+2"?  A positive exponent then directly indicates how many digits there are to the left of the decimal place.  Another example: "0.0045" in scientific notation is "4.5E-3" but wouldn't it be better as "0.45E-2" where the negative exponent directly indicates zero padding to the right of the decimal place?  Hmm...

You must be logged in to post a reply. Please log in or register for a new account.