Hex Calculator
Finally a new app for my apps page, pattern-solver was starting to get lonely…
The idea for this app came from my frustration with not finding a decent hexadecimal convertor online. I was working on an assignment that required calculating offsets from memory addresses given in hexadecimal form, which meant I had to convert the address to decimal, add the number, and convert back. Tedious and inefficient.
I'm still surprised there isn't a half decent calculator online that supports hexadecimal, or even normal math expressions. Most sites I found had some truly horrific UIs, the worst offender was a site with 2 inputs, a dropdown menu, and a button. You performed a calculation by typing in a number, selecting the operator from the dropdown menu, and typing in another number before finally clicking the "calculate" button. That's at least 5 clicks for no reason!
My vision for this calculator was a single input window, and the user would type math expressions that would be computed live on-screen. Of course, there would also be hexadecimal support, as that was the original goal.
Implementation
Solver
You can find the app here. This calculator was originally coded in Python, and then ported to JavaScript.
The biggest component of this would definitely be the math expression solver. At first this seemed daunting but it's not too bad once you wrap your mind around it. I visualized a math expression as a sequence of atomics separated by operators, and the main flow of the program would be to continously compute a new atomic, using 2 atomics and the operator between them, until there was a single atomic left: the final answer.
The exception to this would be brackets, which had to be computed recursively before the atomics were computed.
Going back to that idea of "a sequence of atomics separated by operators", I replace the arguments and operator in the string with the final result, all in place. This made debugging much easier as I could see how the expression changes with each iteration. When the sequence has no more operators, it is considered solved.
The 'Hex' part of 'Hex Calc'
This was very simple, I just translated all hexadecimal values to their decimal equivalent at the start of the program, so there was no confusion later on. Users can define a hex value by pre-pending '0x' before the hex value they want to represent.
Special tidbits
I also added bit shifting to make the experience more complete.
Problems
I had a few minor problems with this project, all of which I found amusing for some reason.
- "-5" was being considered as "something minus 5", which was crashing since it expected a left operand. This was fixed by assigning all operators a special non-english character (characters 0xE0 to 0xE6).
- "bedmas" was being followed very literally, for example the expression "5 - 3 + 2" would choose the addition first, resulting in 0 instead of 4. This was fixed by assigning each operator a tier in "bedmas" order, but operators on the same tier would follow left-to-right order as a backup.
- The bit shift operator was 2 characters (">>" or "<<"), which went against the assumption that each operator would be a single character. Fixed the same way the first bullet point was.
- A negative atomic returned from a recursive call in the bracket solving portion would shift the whole expression by a character (due to the negative), throwing off the pre-computed positions of each operator. Fixed by rewriting the code, because pre-computing operator positions is a foolish idea.
Design Choices
Following my rounding errors in pattern-solver, I decided to forgo floating point calculations. The division operator is implemented via integer division, and all decimal inputs throw an error. Call it a cope, but I think having the calculator only work with integers has a nice aesthetic to it. I was planning on making the UI look like a old CRT computer screen but never got around to it.