MathPad Help

MathPad is an algebraic equation solver. Enter variables and equations, and MathPad automatically detects unknowns and solves using root-finding. Solve forward or backward — give it any combination of knowns and unknowns.

Contents

Getting Started

MathPad organizes work into records, each with a formulas editor and a variables panel. Use the sidebar to create, rename, and switch between records. Open multiple records as tabs.

  1. Type variable declarations and equations in the formulas editor
  2. Click Solve (or press Ctrl+Enter) to compute results
  3. Edit values in the variables panel to quickly change inputs and re-solve

For a hands-on walkthrough, open the records in the Tutorial category in the sidebar — they cover the language and the app step by step, from a first equation through tables, dates, and the workflow tools.

The sidebar lists every record, grouped by category. On narrower screens it's hidden behind the hamburger menu (☰) in the header.

Category controls

Preview vs persistent tabs

Single-click a record in the sidebar to open it as a preview tab (italicized, single slot — opening another preview replaces it). A preview is promoted to a persistent tab when you edit the record, rename it, change a setting, or double-click it. Persistent tabs survive reloads; previews do not.

Records

Variables

Variables are declared with a name followed by a marker that determines their behavior:

SyntaxTypeBehavior
var: valueInputPersistent — keeps value across Solve and Clear
var<- valueInputCleared by the Clear button
var<<- valueInputFull precision, cleared by Clear
var:: valueInputFull precision, persistent
var->OutputCleared and recomputed on Solve
var->>OutputFull precision, cleared on Solve
var:>OutputPersistent output — recomputed on Solve, kept on Clear
var:>>OutputPersistent output, full precision
var[lo:hi]:InputConstrain root-finding search range
var[lo:hi:step]:InputWith explicit step for Brent's grid scan
Full precision markers (::, <<-, ->>, :>>) store and display values with maximum precision instead of rounding to the record's decimal places setting.
Limits are always linear — auto-swapped if reversed ([50:0] = [0:50]). Limit expressions can reference other variables (y[0:x*2]<-); the solver defers a variable until its limit dependencies are solved. The ° format marker is display-only (not a solver signal). For a search that wraps through 0°, write a linear range extending past 360 — e.g., cmg[327.8:365.5]° covers the 37.7° arc. Trig is periodic so Brent’s evaluating 365° equals evaluating 5°.

Input vs Output

Input markers (:, <-, <<-, ::) define variables you provide values for. Output markers (->, ->>, :>, :>>) define variables that MathPad computes. Output variables are cleared before solving so the solver can fill them in.

Definitions

A variable whose value is an expression (not just a number) acts as a definition:

area: length * width
circumference: 2 * pi * radius

Definitions are evaluated in dependency order — out-of-order and chained dependencies are handled automatically.

Equations

An equation is any line with = between two expressions:

distance = speed * time
a**2 + b**2 = c**2

If all variables have values, MathPad checks that both sides balance. If there's an unknown, it solves using Brent's root-finding method.

For systems of equations with multiple unknowns, the solver algebraically rearranges each equation to isolate every possible variable (both directions — x = z/2 yields x and z substitutions), then uses a recursive backtracking search. It tries small combinations of substitutions first, letting Brent's find one-unknown reductions; if a branch doesn't balance, it backtracks and tries another. Declaring answer variables with a range hint (x[low:high]<-) helps pick the desired root when multiple valid solutions exist.

Degree Equality

Use for mod-aware comparison (mod 360 in degrees mode, mod 2π in radians):

heading =° target_heading

This correctly handles wraparound — e.g., 359° and 1° are only 2° apart. Also works as a logical operator in expressions, returning 1 (true) or 0 (false).

Multi-line Equations

Wrap long equations in curly braces:

{long_expression_a + long_expression_b
 = long_expression_c + long_expression_d}

Number Formats

Number Literals

FormatExample
Decimal123, 3.14, 1.5e-10
Base literalff#16 (hex), 1010#2 (binary), 77#8 (octal)
Percent literal5% (stored as 0.05)
Degree literal400° (stored as 400, no mod)

Small values in Float

In Float format, the decimal-places setting is a minimum precision for small numbers, not a hard cap. A value below 1 is shown with at least one more significant figure than your places setting, so it isn't crushed to a couple of digits — at 3 places, 0.0284130625 displays as 0.02841, not 0.028. This keeps small results precise enough to stay consistent with larger related values, so an equation and its algebraic rearrangement both balance.

If a number has more leading zeros than your places setting, it switches to scientific notation instead of a long run of zeros — at 3 places, 3.14×10⁻¹⁴ shows as 3.142e-14 rather than 0.0000000000000314. Full-precision outputs (->>) follow the same rules, showing every significant digit the value carries.

Format Prefixes

Add a format prefix before the marker to control display:

PrefixExampleDisplay
$price $: 1234.5$1,234.50 (always 2 decimals, comma grouping). The currency symbol is configurable in record settings.
%rate %<- 7.5%7.5% (stored as 0.075)
°angle °: 40040° (degrees mode: mod 360 with °; radians mode: mod 2π without symbol)
@dwhen @d: 4/1/202604/01/2026 (date, locale format)
@tdur @t: 1:30:001:30:00 (duration H:MM:SS)
#16hex #16-> 255FF (bases 2-36)

Expression Outputs

Format suffixes also work on expression outputs:

total cost: qty * unit_price
(total cost)$->
(rate)%->
(heading)°->
(Now)@d->

Operators

Listed by precedence (highest to lowest):

OperatorDescription
- + ~ !Unary: negate, plus, bitwise NOT, logical NOT
**Power (right-associative)
* /Multiply, Divide
+ -Add, Subtract
<< >>Bit shift left, right
&Bitwise AND
| ^Bitwise OR, XOR
== != < <= > >=Comparison (returns 1 or 0)
&&Logical AND
|| ^^Logical OR, XOR

Built-in Functions

Function arguments are separated by semicolons: f(a; b; c)

Math

FunctionDescription
Abs(x)Absolute value
Sign(x)-1, 0, or 1
Int(x)Integer part (truncate toward zero)
Frac(x)Fractional part
Round(x)Round to nearest integer
Floor(x)Round down
Ceil(x)Round up
Mod(a; b)Remainder (always non-negative for positive b)
Sqrt(x)Square root
Cbrt(x)Cube root
Root(x; n)Nth root
Exp(x)e raised to x
Ln(x)Natural logarithm
Log(x)Base-10 logarithm
Fact(n)Factorial (n!)
Pi3.14159...
RandRandom number 0 to 1

Trigonometry

Uses degrees or radians depending on the record's Degrees mode setting.

FunctionDescription
Sin(x), Cos(x), Tan(x)Trigonometric functions
ASin(x), ACos(x), ATan(x)Inverse trig
SinH(x), CosH(x), TanH(x)Hyperbolic
ASinH(x), ACosH(x), ATanH(x)Inverse hyperbolic
Radians(deg)Convert degrees to radians
Degrees(rad)Convert radians to degrees

Date and Time

Dates are stored as epoch seconds (seconds since Jan 1, 1970 UTC). Use @d to format as a date and @t for durations:

Durations of 24h or more display with a day count (2d 5:30:00 is 2 days plus 5 hours 30 minutes); the parser accepts the same form on input.

FunctionDescription
NowCurrent date/time as epoch seconds
Date(y; m; d [; h; min; s])Create date as epoch seconds
Days(d1; d2)Days between two dates
Year(d), Month(d), Day(d)Extract date components
Weekday(d)Day of week (1=Sunday, 7=Saturday)
Hour(d), Minute(d), Second(d)Extract time components
Hours(d)Decimal hours of day from date
TimePart(d)Seconds since midnight (for @t display of time-of-day)

Example: start @d: 4/1/2026 14:30Days(start; Now)@t-> shows elapsed time

Control Flow

FunctionDescription
If(cond; then; else)Conditional — returns then if cond is non-zero, else otherwise
Choose(n; v1; v2; ...)Returns the nth value (1-based)
Min(a; b; ...)Minimum of values
Max(a; b; ...)Maximum of values
Avg(a; b; ...)Average of values
Sum(a; b; ...)Sum of values

Iteration

Sum or multiply an expression over an integer range. The second argument is the index variable's name; the index runs from start to end inclusive and is in scope only inside expr.

FunctionDescription
Sum(expr; var; start; end)Sum of expr evaluated with var = start..end
Prod(expr; var; start; end)Product of expr evaluated with var = start..end
Sum(a; b; ...)Variadic form — sum of fixed arguments
Avg(a; b; ...)Average of fixed arguments (no binding form)

Example: Sum(1/k**2; k; 1; 1000) — partial sum of the Basel series

Other

FunctionDescription
isClose(a; b; places)1 if a and b are equal within tolerance, 0 otherwise
modIsClose(a; b; n; places)Like isClose but mod-aware (equal modulo n) — useful with °= angles, e.g. modIsClose(a; b; Perigon; Places)
Tau2π (always)
Perigon360 in degrees mode, 2π in radians mode
PlacesCurrent record's decimal places setting

For financial helpers like pmt and compound, see the Default Functions record below.

User-defined Functions

Define functions in any record using the syntax:

f(x; y) = expression using x and y

Define functions in the special "Functions" record to make them available to all records. Function parameters use semicolons as separators, just like built-in functions.

In the formulas editor, a definition's signature — the name(arg1; arg2; …) part up to the = — is shown with a subtle highlighted band, so a function definition stands out from an ordinary equation at a glance.

Function bodies can reference values from the Constants record and call other user-defined functions and built-ins. They cannot read variables from the calling record — only the function's parameters and the global environment (constants + functions) are visible inside the body. Shadowing a constant locally (e.g. c: 1 in a record that uses a function referencing c) does not change the function's behavior — it always sees the canonical value from the Constants record. This keeps functions self-contained and predictable.

Default Functions record

A fresh MathPad ships with these functions already defined in the Functions record — available everywhere unless you edit or remove them:

FunctionDescription
pmt(pv; rate; n; fv)Loan / annuity payment (returns a negative value for cash flowing out)
compound(pv; rate; n)Compound-interest future value: pv * (1 + rate)**n
ctof(c) / ftoc(f)Celsius ↔ Fahrenheit conversion
hypot(a; b)sqrt(a**2 + b**2)
disc(a; b; c)Quadratic discriminant b**2 - 4*a*c

Edit the Functions record to add, remove, or modify these.

Special Records

NamePurpose
ConstantsVariables defined here are available in all other records
FunctionsUser-defined functions available to all records
Default SettingsSettings template for newly created records

Variables Panel

The variables panel (above the formulas editor) shows a structured view of all variables:

--Variables-- Section

Add a --Variables-- line in the formulas editor. Only lines below this marker appear in the variables panel. Lines above it (formulas, equations) are hidden from the panel.

Comments

Text in double quotes is treated as a comment and ignored by the solver:

"This is a comment"
x: 42    "the answer"

Comments after a variable declaration appear in the variables panel.

Pre-solve Values

Access a variable's value from before the current solve started:

SyntaxDescription
x~Pre-solve value of x (error if none)
x~?1 if x has a pre-solve value, 0 otherwise

Example: counter: if(counter~?; counter~ + 1; 0) — increments each time you solve

Inside a table, grid, or vectorDraw body, ~ refers to the value from the PREVIOUS ROW (or cell), not the previous solve. The first row sees no pre-solve values (so x~? is 0); subsequent rows inherit from the previous row. This is the foundation of running-total patterns:

table("Investment growth") = {
  year: 1..10
  balance = if(balance~?; balance~; 0) * (1 + rate) + contrib
  ...
}

Tables, Grids, and Vector Diagrams

Use table to iterate a variable over a range and display results in columns. Use tableGraph to render those rows as an SVG line graph. Use grid for 2D cell grids with two iterators. Use vectorDraw to render SVG vector diagrams (navigation, polar, or cartesian).

Table (Columnar Output)

table("Distance vs Time") = {
  distance = speed * time
  speed: 60
  time<- 1..5
  time->
  distance->
}

Multiple iterators iterate as nested loops over the cartesian product. The first-declared iterator is the outermost loop (changes slowest); the last-declared is innermost (changes fastest). Iterator bounds are evaluated once up-front, so inner iterators cannot depend on outer iterator values.

tableGraph (Line Graph)

Same body syntax as table, but rendered as an SVG line graph. Column 0 is the X-axis; remaining columns are Y series (one line each).

With multiple iterators, line grouping is opt-in: an inner iterator becomes a line-grouping variable only if it has a iter-> output column. The column's label is used in the legend (e.g. Y y-> produces Y = 1.0). Without y->, the inner iterator just sweeps silently and only one line is drawn.

tableGraph("z = x^y") = {
  z = x**y
  x: 1..2..0.1
  y: 1..2..0.1
  X x->
  Y y->
  Z z->
}

The above renders 11 lines (one per y value), each plotting z against x, labeled Y = 1.0, Y = 1.1, … Y = 2.0.

Hover the mouse over a graph to get a crosshair and a readout of the (x, y) coordinates at the pointer.

Grid (2D Cell Grid)

grid("Multiplication") = {
  z = x * y
  z<-
  x<- 1..5
  y<- 1..5
  x->
  y->
  z->
}

Inline expressions in titles

Wrap an expression in backslashes inside the title string to interpolate its current value:

table("Loan at \rate%\ over \years\ years") = { ... }

The expression is evaluated against the record's variables and re-rendered each Solve. Useful for self-labeling tables and graphs whose subject depends on the inputs.

Body Declarations

SyntaxRoleDescription
x<- 0..10IteratorRange from 0 to 10, step 1
x: 0..10..2IteratorRange with step 2
z<- or z:UnknownBare declaration — solved by equations
z[lo:hi]<-Unknown with limitsConstrain search range
v: 10DefinitionExpression value set per row
Label z->OutputOutput column with optional label

Equations

Include equations inside the body. If the body has no equations, the table inherits equations from the surrounding record. If the body has any equations, only those are used.

Options

An optional font size can be specified as a second argument:

table("Title"; 12) = {
  ...
}

Click a table title to collapse or expand it.

Grid hover: Hovering over a grid cell highlights the row, column, and header for easy reading.

Vector Diagrams

Use vectorDraw to render SVG vector diagrams. The second argument is the coordinate type (required) and selects how each vector's four outputs are interpreted:

TypePair semanticsConvention
navigation(direction, magnitude)0° = up (north), positive angles clockwise — compass bearings
polar(direction, magnitude)0° = right (east), positive angles counter-clockwise — math convention
cartesian(x, y)raw coordinates — no angle handling

Each vector is defined by four outputs: a start pair (absolute position from the origin) and an end pair. For navigation and polar the end pair is the relative displacement — (direction, magnitude) added to the start. For cartesian the end pair is the absolute destination point (x, y).

vectorDraw("Wind Triangle"; navigation) = {
  "equations..."
  tc °->          "start direction (bearing)"
  start_mag ->    "start magnitude"
  Label end_dir °->   "end direction (labels the vector in the legend)"
  end_mag ->      "end magnitude (relative displacement)"
}

Labels on the end pair identify the vector in the legend. Direction columns use the record's degrees/radians mode (cartesian columns are unitless). Collapsible titles and optional font size work just like tables — for vectorDraw the font size is the third argument: vectorDraw("Title"; polar; 12).

The legend and all vector outputs respect the record's decimal places, strip zeros, and group digits settings.

Solve Status Indicator

When a table, grid, or vector diagram doesn't fully solve, its title shows (n/m solved) indicating how many rows, cells, or unknowns were successfully solved. This indicator is hidden when everything solves.

Import / Export

Access Import/Export from the sidebar buttons.

Google Drive Sync

Optional cloud sync keeps all your records on Google Drive and across your devices. Use the Drive control in the header (the cloud / your initial) to sign in. Without it, MathPad still works entirely in your browser — Drive is purely additive.

When two devices disagree

If this device's records and the Drive file differ (e.g. you edited on another device), MathPad asks how to combine them — never overwriting silently:

Open, Save As, and deleting the file

Keyboard Shortcuts

Cmd substitutes for Ctrl on Mac.

ShortcutAction
Ctrl+Enter / Ctrl+SSolve current record
Ctrl+Shift+EnterSolve and append a --- Table Outputs --- text section
Ctrl+Shift+SClear inputs and outputs (same as the Clear button)
Ctrl+ZUndo (routes to the active editor; also undoes Solves)
Ctrl+Y / Ctrl+Shift+ZRedo
Tab (in formulas)Indent line by 2 spaces (or selection)
Shift+Tab (in formulas)Outdent line by 2 spaces
Ctrl+/ (in formulas)Toggle // line comment on selection
Tab / Shift+Tab (in vars panel)Commit edit, Solve, and cycle to the next / previous input
Enter (in vars panel)Commit edit and Solve
EscapeRevert edited variable value, unfocus formulas, close modals, or stop a running solve

Solve Button Modifiers

Hold modifier keys when you click the Solve button:

ClickAction
SolveNormal solve
Shift+clickSolve, then append a --- Table Outputs --- text section
Ctrl+clickSolve in trace mode — appends a *--- Solve Trace --- section showing the steps the solver took. Useful when a result surprises you.
Ctrl+Shift+clickTrace plus table outputs

While a solve is running, the Solve button turns red and reads Stop — click it (or press Escape) to cancel. Editing the record, or switching to another record, also cancels a running solve. Most solves finish instantly, so you'll usually only see this on a large table or a heavy computation.

Record Settings

Click the gear icon to configure per-record settings:

SettingDescription
CategoryOrganize records into collapsible groups in the sidebar
Decimal PlacesNumber of decimal places for output (default 2)
FormatFloat, Scientific, or Engineering notation
CurrencySymbol for $ format ($ € £ ¥ ₹ ₩ ₱ ₺ ₴ ₫ ₡ ₽ ₸ ₼ ₾ ৳)
Strip ZerosRemove trailing zeros from output
Group DigitsAdd comma separators (1,234,567)
Degrees ModeTrig functions use degrees instead of radians; ° format displays mod 360 with ° suffix (radians mode displays mod 2π without symbol)

The settings panel also shows the record's Created and Modified timestamps. Modified updates only when you edit the formulas text directly — not when you solve, clear, or change variable values in the variables panel.

Example: Loan Calculator

"Loan calculator"

--Functions--
pmt(pv; rate; n; fv) = -(pv + fv / (1 + rate)**n) * rate / (1 - (1 + rate)**-n)

--Equations--
pmt = pmt(pv; rate/12; years*12; fv)

--Variables--
pv $<-   $100,000     "present value (loan or annuity)"
fv $<-   $0           "future value (balloon payment)"
rate %<- 6.125%       "annual interest rate %"
years <- 30           "number of years"
pmt $<-               "monthly payment"

How it works:

  1. --Functions-- and --Equations-- are visual labels — only --Variables-- is a real section marker (controls what shows in the variables panel)
  2. The function definition is reusable from anywhere below it
  3. The equation ties the function to the variables MathPad will solve for
  4. The variables section lists inputs and outputs — $ formats as money, % as percent
  5. Click Solve to calculate pmt: -$607.61
  6. To solve backwards, set pmt: -$2,000 and clear pv, then solve — MathPad finds pv: $329,158.21