You are browsing as a guest. Sign up (or log in) to start making projects!

calc82: Web Scientific Calculator

  • 7 Devlogs
  • 63 Total hours

Web calculator which simulates a real calculator from a certain brand :)

Open comments for this post

9h 55m 23s logged

calc82: Devlog #7 21/07/2026

calc82: because calculators are for everyone

This devlog follows the introduction of an actual user interface to my calculator.

🌟 New functionality summary

  • Grid of calculator buttons
  • Different button output when modifiers pressed
  • Navigation buttons work
  • Calculator resembles a real calculator

👇 Button handling

The calculator needed buttons resembling that of the Casio to fulfil my purpose.

Buttons are dynamically built from an array, which defines their labels and actions. This allows easy changes.
For most buttons, the area surrounding the button also acts as a clickable area for better touch input. However, I didn’t find an easy way to do this for the navigation buttons (which are positioned off the grid).

🎨 CSS

CSS Grid allows a 2D layout system based on rows and columns. It has been supported by all major browsers since October 2017.

CSS Grid was used, as it allows consistent positioning across browsers. In addition, relative units were used to prevent resizing the calculator from affecting it. This should make it easier to make dynamic sizing in the future.

🗒️ Notes

Accessibility
<button>s are preferred over clickable <div>s because they work with screen readers and legacy browsers. However, I also made the surrounding elements clickable for a better touch experience. Also, keyboard input will make use significantly easier for computer users.
Aesthetics
The CSS applied so far is purely functional. In the future, I will improve the aesthetics of the calculator through CSS - but for now, this barebones look makes development easier and more focused.

📈 Next steps

The todo list was getting too empty, so it has been updated with new tasks
Immediate:

  • Add remaining functions
  • Add keyboard shortcuts

Medium:

  • Add menu system and settings
  • Multi-line calculation (Ans) and setting variables
  • Implement polar/rectangualr conversion
  • Add other modes (STAT, VERIFY)
  • Add

Long-term:

  • Create a test suite to ensure there is no unwanted behaviour
  • Ship :)
0
0
4
Open comments for this post

9h 35m 21s logged

calc82: Devlog #6 18/07/2026

calc82: because calculators are for everyone

This devlog follows the further development of algebraic I/O to my calculator, including turning this into an actual result.

🌟 New functionality summary

  • Input and output formatting through KaTeX
  • Square root, arbitrary root, mixed fraction, and absolute values
  • Tokeniser now directly reads input tokens
  • Errors now move the cursor to the position where it occurred

🌊 New program flow

inputHandler -> [input tokens] -> tokeniser -> [calculator tokens] -> parser -> AST -> evaluator -> result
This:

  • improves speed (compared to parsing text)
  • allows cursor to be moved to error location since we never flatten to text
    You might notice I have two sets of tokens. They are similar, but input tokens deal with digits and combined symbols (sin(), and calculator tokens are whole numbers and separated symbols.

🗒️ Notes

Avoiding the lazy route
My first approach was turning the input tokens into a string, which my tokeniser already knew how to deal with. However, this added much processing overhead and made it harder to find out the position at which errors occurred. Spending the time to implement the token conversion made this step much easier

Misplaced math errors
When implementing error handling, I passed down the original position of each token in the input token array down to each step of the calculation process. However, because my evaluator is recursive, it would constantly update the error position to the latest token, meaning the errors were always placed at the end. This was an easy fix in the end - but hard to spot!

📈 Next steps

Immediate:

  • Buttons input
  • Add remaining functions (once buttons are added can be done)

Medium:

  • Multi-line calculation (Ans) and setting variables
  • Implement polar/rectangualr conversion (delayed until UI is more fleshed out)
  • Build UI

Long-term (but getting closer!):

  • Create a usable UX
  • Ship :)
0
0
4
Open comments for this post

9h 40m 15s logged

calc82: Devlog #5 16/07/2026

calc82: because calculators are for everyone

This devlog mainly follows the addition of algebraic I/O to my calculator. This is just a check-in since I was getting close to 10 hours since the last devlog - I still have some work to do on this aspect before I move on.

🌟 New functionality summary

  • Input and output formatting through KaTeX
  • Fractions and powers formatted correctly in the input
  • Ability to intuitively traverse the input with arrow keys

⚖️ Algebraic IO with KaTeX

I decided on KaTeX because it is both fast (no reflow!) and does not rely on dependencies.

KaTeX is a math formatting library that uses LaTeX commands to create beautiful equations from code.
For example,
\frac{2^{\frac{3}{4}}}{4\sin(30)}\times 2\pi
turns into the attached image.

Input is currently captured directly from the keyboard to build a 1D array of tokens. The tokens are then converted into KaTeX formatting for algebraic display.

In the future, there will also be buttons onscreen as an alternative.

Fractions and powers

Fractions and powers cannot be represented as a single token. Rather, fractions have a beginning, middle and end, and powers have a beginning and end. The program traverses the array to decide where to put them (and take them out for deletion).

🗒️ Notes

The cursor
It is surprisingly difficult to make a vertical bar to act as a cursor in KaTeX, without affecting the spacing of the rest of the expression. For now, I am using a \clap{\rule{0.1em}{0.5em}} for the cursor, but I am looking to replace this with custom CSS in the future.

Replicating exact behaviour?
The fx-82 has some interesting behaviour wherein an empty power is not allowed to exist directly after another power. I am unsure whether I should replicate this - but for now, I am leaving it out.

Dealing with broken LaTeX
I have been able to get the display pretty bulletproof when it comes to not producing broken LaTeX. However, I’m sure there’s something I haven’t run into in debugging! I want to have this be dealt with gracefully rather than blowing up in the user’s face.

📈 Next steps

Immediate:

  • Implement mixed fractions, roots, and Abs to algebraic display
  • Make the input token array able to be parsed into the AST to be calculated

Medium:

  • Multi-line calculation (Ans) and setting variables
  • Implement polar/rectangualr conversion (delayed until UI is more fleshed out)
  • Build UI

Long-term (but getting closer!):

  • Create a usable UX
  • Ship :)
0
0
1
Open comments for this post

7h 7m 16s logged

calc82: Devlog #4 14/07/2026

calc82: because calculators are for everyone

This devlog mainly follows the addition of fractional I/O to my calculator.

🌟 New functionality summary

  • Fractional input, including fractions
  • Computation of fractions - add/sub,div/mult,power,root
    • other operations convert the fraction to a decimal
  • Fractional output (temporary UI)
  • LCM/GCD
  • separate execute and fraction/decimal converting buttons

🔢 fractional io :)

I defined a separate fraction data type: it’s like a decimal, but with a numerator and denominator, and optionally a whole component: for example, 1 and 1/3, or 4/3.

Using fractions means that numbers can be represented more naturally and precisely. I.e. 1/7 instead of 0.142857143

🧮 Fractional calculation

Additionally calculations can be made more precise. For example (1/7) * (2/3) can be directly computed by multiplying the numerators and denominators.

My implementation attempts to convert user input and the products of divisions into fractions wherever possible in order to chase this precision.

🗒️ Notes

Web design is not my thing
I realised the importance of UI and UX (user experience) by looking at other projects on Stardance. As of the current iteration, this project lacks this a bit..

But I will give it a shot
My next developments will begin to focus more on this - starting with the algebraic input, and eventually moving onto the CSS and design aspects.
I am also considering whether I should use a Javascript framework.

📈 Next steps

Immediate:

  • Create algebraic display functionality

Medium:

  • Multi-line calculation (Ans) and setting variables
  • Implement polar/rectangualr conversion (delayed until UI is more fleshed out)
  • Build UI

Long-term (but getting closer!):

  • Create a usable UX
  • Ship :)
0
0
1
Open comments for this post

6h 32m 8s logged

calc82: Devlog #3 10/07/2026

calc82: because calculators are for everyone

Oh dear, looks like I lost 4 hours of counted time in the last devlog… let’s try to make this one a bit shorter!

This devlog follows the implementation of the other inline functions of the calculator:

🌟 New functionality summary

  • inverse and hyperbolic trig
  • arbitrary roots
  • absolute value
  • percent
  • random numbers: Ran and RanInt
  • scientific notation: *10^x / E
  • combinatorics: nPr and nCr
  • variables (not yet adjustable)

📋 Implementation details

Implementing most of this functionality followed the same general steps:

  1. identify
  2. implement
  3. test.

As I undertook this process. other dependent requirements popped up - such as the implementation of multivariable functions, which in turn required the expansion of the tokeniser and parser.

Also, I implemented degrees, radians, and gradians modes into the calculator, and the associated functions (as postfix expressions - e.g. sin(30d) for degrees).

🗄️ decimal.js changes

Finally, I applied some further changes to decimal.js.:

  • Rounding now depends on the closeness of the output to a known value, rather than the input, reducing unnecessary rounding
  • Near-decimal values close to 0, 0.25, 0.5, 0.75 and 1 are now caught.

🗒️ Notes:

Remembering that Javascript is weird
NaN === NaN is FALSE! Spent a good 10 minutes figuring this one out. The solution was to use isNaN().

Fixing negative-base powers:
(-8)^(1/3) should equal 2 but returns NaN
Fixed by taking the denominator from the output of a decimal.js toFraction() function, which attempts to create a rational fraction. This overcomes the tiny precision loss and evaluates the function correctly

📈 Next steps

Immediate:

  • Add fractional I/O
  • Implement polar/rectangualr conversion

Medium:

  • Create algebraic display functionality
  • Multi-line calculation (Ans) and setting variables

Long-term:

  • Build UI
  • Ship :)

This has been a bit of a shorter devlog. But I’m still proud of what I achieved! Thanks so much for reading. If you have any suggestions, please leave me a comment. Take care

0
0
1
Open comments for this post

14h 5m 48s logged

calc82: Devlog #2 08/07/2026

calc82: because calculators are for everyone

This devlog follows the handling of nasty floating point errors in my web calculator - inspired by and designed to work with Casio’s fx-82au.

I realised that relying purely on the Javascript math system was unsuitable for a scientific calculator that works with decimal numbers. This is due to binary floating point not translating well to decimal.

0.1+0.2=0.30000000000000004 >:(

I researched and considered a few approaches.

🥧 Symbolic simplifier?

The idea behind this is to perform algebra and avoid evaluating constants and functions to values until strictly necessary. However, the scope of this seemed massive, and I did not observe this behaviour in the Casio.

🔟 Decimal arithmetic

Instead, I stumbled upon the fact that decimal arithmetic can be implemented in a computer. While IEEE floats use binary representation, there is no reason we cannot use decimals internally, avoiding errors that arise from conversion. Decimal floats can be stored by:

  • Sign: +/-
  • Mantissa: the number itself, in my case an array of digits
  • Exponent: what power of 10 the number should be multiplied by.

I started implementation, made decent progress, but found out that I was re-doing work that was already done by other people.

🗄️ Decimal.js

I found the decimal.js library after researching how to handle decimal addition. Implementing this quickly fixed my floating point errors, but did not fix trig approximation.

👀 Observing the calculator

I observed some of the behaviour of the real calculator to work out how it functions.

  • Handles small-angle approximation based on a threshold
  • Drops precision as the trig function argument value increases
  • Appears to use a 15-digit mantissa
  • Refuses to evaluate trig functions with argument above a certain limit

I tried my best to implement the behaviour I observed, some of which required editing the code of the decimal.js library.

📝 Editing decimal.js

The decimal.js library uses more than the set precision for some internal calculations. However, arithmetic with pi is otherwise only the set precision, causing drift.

My fix for this was to adjust the internal pi value to match the mantissa size of the real calculator.

Troubles with the library

When given a less accurate value for pi (in line with that of the real calculator) sine quadrant is incorrectly calculated. I found that the isOdd function is flawed!

function isOdd(n) {
return n.d[n.d.length - 1] & 1;
}

I replaced it with one that works for my use case (if less efficient):

function isOdd(n) {
    return n.mod(2).eq(1);
}

I need to see if this is just due to my low precision pi, or an actual problem in the library, in the future. But for now my issue is fixed.

I also found an error in the cosine function: if (x.isZero()) return x needed to be changed to if (x.isZero()) return new Ctor(1).

Again, I’m going to have to look into this more before submitting a pr or anything, since decimal.js is not made for such an imprecise pi.

🗒️ Notes

Deviations
There are still small deviations between my calculator and the real one at really, really large trig angles.

One idea to reduce error could be optimising the order of operations in the AST to prevent dropping precision unnecessarily. I might explore this later

However, I want to press on with other features, instead of tiny inaccuracies that would never show up in real-world use. I have slightly rearranged the to-do list below.

📈 Next steps

Immediate:

  • Implement the other calculator buttons and functions
  • Add fractional I/O

Medium:

  • Create algebraic display functionality
  • Multi-line calculation (Ans) and variables

Long-term:

  • Build UI
  • Ship :)

Thanks so much for reading! If you have any suggestions, please leave me a comment. Until next time

0
0
2
Open comments for this post

6h 25m 40s logged

calc82: Project Introduction and Devlog #1

calc82: because calculators are for everyone

The aim of this project is to create a free, software-based browser calculator which mimics the behaviour of the Casio fx-82au. This is the most common calculator in high schools in my country.

🔥 Motivation

My motivation for this project is the following:

  1. calculators are cool
  2. i dont always have my calculator on me
  3. (most notably) not everyone has access to a scientific calculator

🎯 Approach

I will take a black-box reverse engineering approach. This means analysing the inputs and outputs of the calculator and attempting to replicate the behaviour without looking at the underlying code. This along with avoiding patents and copyright should keep the project okay legally.

📈 Goals and scope

The final goal for the project is to create a fully functional calculator (obviously) which works on most types of devices. This means both touch and keyboard input, resolution scaling, wide browser support…

I have moderate experience with creating web apps. and a lot of experience using this calculator. so this project should be pretty fun :)

Devlog #1 06/07/2026

This devlog covers the initial development of the parts of the calculator that do math. Essentially turning an input expression into an output.

I chose a high-level structure similar to that used by programming language syntax analysers. That is:

Input -> Tokeniser -> Parser -> Evaluator -> Output

🪙 Tokeniser

yes, with an s >:(
The tokeniser converts the input into a list of tokens (think individual pieces of the expression). It does this by scanning the input string and identifying what each character corresponds to. The tokeniser only knows what each symbol is, not what it does. Then it passes the token array to the…

🌲 Parser

The parser converts the token array into an Abstract Syntax Tree (AST). Essentially this is a tree which shows how the expressions should be evaluated in order to produce the desired output. This properly lets me implement order of operations.

The exact type of parser I am using is a recursive descent parser. It attempts to match the tokens with known symbols recursively, meaning i can rely on the call stack :)

The order of operations can be defined by the order of function calls within the parser.

🧮 Evaluator

The evaluator’s job is easy: it just traverses the tree made by the parser and runs the necessary operations. Because all of the hard work regarding order of operations has been done by the other components, implementing the evaluator was really easy. Its also recursive. your call stack is gonna love me for this

🗒️ Notes

Why not eval?
It’s true that JavaScript has a perfectly good expression parser, which I could have used. However, its behaviour is more suited to a programming language than a calculator.
For example, 4(2+3) should implicitly multiply, but will instead complain TypeError: 4 is not a function. Writing my own system gives me more flexibility to make the calculator how I want.

Floating point precision
Because it uses Javascript’s internal math engine, i have floating-point problems. This results in expressions like
sin(2pi) = -2.44929360e-16
I will likely fix this by using a math library, or a novel approach.

Last-minute catch
I was just writing an example for this devlog when I found that .3ln(4)*5^2 raised an error. In fact, ANYTHING * or / followed by x^n would error - but other operators wouldn’t. This was a quick fix, but I’m glad I caught it!

📈 Next steps

Immediate:

  • Fix math imprecision
  • Add fractional I/O

Medium:

  • Create algebraic display functionality
  • Multi-line calculation (Ans) and variables

Long-term:

  • Make the calculator functionally equivalent to the fx-82
  • Build UI
  • Ship :)

Thanks so much for reading! If you have any suggestions, please leave me a comment

0
0
4

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…