Expression Simplifier Calculator
Simplify algebraic expressions by combining like terms, expanding parentheses, and reducing basic polynomial forms.
What the Result Means
The simplified expression is an equivalent form of the expression you typed. It keeps the same value for the same variable values, but it removes unnecessary repetition by collecting like terms and expanding supported parentheses.
For example, 2x + 3x becomes 5x because both terms contain the same variable part. The calculator also handles multiplication such as 2(x + 1), which becomes 2x + 2.
Method Used by This Expression Simplifier
This tool treats supported expressions as polynomials. It parses the expression, expands multiplication where possible, then combines terms that have the same variable powers.
The calculator supports addition, subtraction, multiplication, parentheses, single-letter variables, nonnegative integer powers, and division by a number. It does not use eval or external algebra libraries.
How to Use the Calculator
- Type an algebraic expression into the input box.
- Use ^ for exponents, such as x^2.
- Use parentheses for grouped expressions, such as 2(x + 3).
- Select how many decimal places should be shown if the result has decimal coefficients.
- Click Simplify Expression to see the equivalent simplified form.
- Use Copy Result if you want to reuse the visible answer.
Worked Example
Suppose the expression is:
2x + 3x – 4 + 2(x + 1)
First, expand the parentheses:
2(x + 1) = 2x + 2
Now rewrite the expression:
2x + 3x – 4 + 2x + 2
Combine the x terms and constant terms:
7x – 2
Common Uses
- Algebra homework: check whether like terms were combined correctly.
- Pre-algebra practice: see how parentheses and signs affect the final expression.
- Equation preparation: simplify each side before solving an equation.
- Polynomial practice: expand simple products such as (x + 2)(x – 3).
Common Mistakes to Avoid
- Writing x2 when you mean x^2. This calculator reads x2 as x times 2.
- Using unsupported functions such as sin, log, square root, or absolute value.
- Trying to simplify rational expressions such as x / x. This tool only divides by numeric constants.
- Forgetting parentheses in expressions like 2(x + 3).
- Using very large powers, which can create long expanded expressions.
Limitations
This expression simplifier is designed for basic polynomial expressions. It can expand and combine many classroom-style algebra expressions, but it is not a full computer algebra system.
It does not factor expressions, solve equations, simplify radicals, simplify trigonometric expressions, or reduce rational expressions with variables in the denominator.
FAQ
Can this calculator show steps?
Yes. It shows the parsed expression, the combined terms, and the final simplified result. The steps are focused on the algebra operations this tool supports.
Does it solve equations?
No. It simplifies expressions only. For example, it can simplify 2x + 3x, but it does not solve 5x = 20.
Can I use parentheses?
Yes. Parentheses are supported, including expressions such as 2(x + 1) and (x + 2)(x – 3).
Does it support exponents?
Yes, it supports nonnegative integer powers such as x^2 and y^3. Very large powers are limited to keep the page fast and readable.
Why did I get an unsupported division message?
The calculator can divide by numbers, such as (x + 2) / 2. It does not simplify division by expressions such as x / (x + 1).
#cd-expression-simplifier-calculator {
–cd-esc-text: #162033;
–cd-esc-muted: #5e6a7d;
–cd-esc-border: #d9e1ee;
–cd-esc-soft: #f5f8fc;
–cd-esc-main: #2357d6;
–cd-esc-main-dark: #183f9b;
–cd-esc-good: #0f766e;
–cd-esc-warn-bg: #fff4e5;
–cd-esc-warn-text: #8a4b00;
–cd-esc-error-bg: #fff0f0;
–cd-esc-error-text: #a32020;
color: var(–cd-esc-text);
font-family: inherit;
line-height: 1.6;
max-width: 1100px;
margin: 0 auto;
}#cd-expression-simplifier-calculator * {
box-sizing: border-box;
}#cd-expression-simplifier-calculator h2 {
margin: 0 0 12px;
line-height: 1.25;
color: var(–cd-esc-text);
}#cd-expression-simplifier-calculator h3 {
margin: 0 0 10px;
line-height: 1.3;
color: var(–cd-esc-text);
}#cd-expression-simplifier-calculator p {
margin: 0 0 14px;
}#cd-expression-simplifier-calculator .cd-esc-intro {
color: var(–cd-esc-muted);
margin-bottom: 18px;
}#cd-expression-simplifier-calculator .cd-esc-tool {
border: 1px solid var(–cd-esc-border);
background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%);
border-radius: 14px;
padding: 20px;
margin: 0 0 28px;
box-shadow: 0 10px 30px rgba(21, 35, 67, 0.07);
}#cd-expression-simplifier-calculator .cd-esc-topline {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 16px;
}#cd-expression-simplifier-calculator .cd-esc-label {
display: inline-flex;
align-items: center;
border-radius: 999px;
background: #e9f0ff;
color: var(–cd-esc-main-dark);
font-size: 13px;
font-weight: 700;
padding: 5px 10px;
}#cd-expression-simplifier-calculator .cd-esc-mini,
#cd-expression-simplifier-calculator .cd-esc-help,
#cd-expression-simplifier-calculator .cd-esc-result-note {
color: var(–cd-esc-muted);
font-size: 14px;
}#cd-expression-simplifier-calculator .cd-esc-field {
margin-bottom: 14px;
}#cd-expression-simplifier-calculator label {
display: block;
font-weight: 700;
margin-bottom: 6px;
}#cd-expression-simplifier-calculator input,
#cd-expression-simplifier-calculator select {
width: 100%;
border: 1px solid var(–cd-esc-border);
border-radius: 10px;
padding: 12px 13px;
font: inherit;
color: var(–cd-esc-text);
background: #ffffff;
}#cd-expression-simplifier-calculator input:focus,
#cd-expression-simplifier-calculator select:focus {
outline: 3px solid rgba(35, 87, 214, 0.16);
border-color: var(–cd-esc-main);
}#cd-expression-simplifier-calculator .cd-esc-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
}#cd-expression-simplifier-calculator .cd-esc-buttons,
#cd-expression-simplifier-calculator .cd-esc-presets {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 12px 0;
}#cd-expression-simplifier-calculator button {
border: 0;
border-radius: 10px;
padding: 11px 14px;
font: inherit;
font-weight: 700;
cursor: pointer;
min-height: 44px;
}#cd-expression-simplifier-calculator #cd-esc-calculate {
background: var(–cd-esc-main);
color: #ffffff;
}#cd-expression-simplifier-calculator #cd-esc-calculate:hover {
background: var(–cd-esc-main-dark);
}#cd-expression-simplifier-calculator #cd-esc-copy,
#cd-expression-simplifier-calculator #cd-esc-clear,
#cd-expression-simplifier-calculator .cd-esc-presets button {
background: #eef3fb;
color: var(–cd-esc-text);
}#cd-expression-simplifier-calculator .cd-esc-presets button {
font-size: 14px;
}#cd-expression-simplifier-calculator .cd-esc-error {
display: none;
background: var(–cd-esc-error-bg);
color: var(–cd-esc-error-text);
border: 1px solid #ffd0d0;
border-radius: 10px;
padding: 10px 12px;
margin: 12px 0;
font-weight: 700;
}#cd-expression-simplifier-calculator .cd-esc-result {
border: 1px solid #bcd0ff;
border-radius: 14px;
background: #f1f6ff;
padding: 16px;
margin-top: 14px;
}#cd-expression-simplifier-calculator .cd-esc-result-label {
display: block;
color: var(–cd-esc-muted);
font-size: 14px;
font-weight: 700;
margin-bottom: 4px;
}#cd-expression-simplifier-calculator .cd-esc-main-result {
font-size: clamp(26px, 5vw, 42px);
font-weight: 800;
line-height: 1.2;
overflow-wrap: anywhere;
color: var(–cd-esc-main-dark);
margin-bottom: 8px;
}#cd-expression-simplifier-calculator .cd-esc-steps,
#cd-expression-simplifier-calculator .cd-esc-terms {
background: #ffffff;
border: 1px solid var(–cd-esc-border);
border-radius: 12px;
padding: 14px;
margin-top: 14px;
}#cd-expression-simplifier-calculator .cd-esc-steps ol {
margin: 0;
padding-left: 22px;
}#cd-expression-simplifier-calculator .cd-esc-terms-box {
overflow-x: auto;
}#cd-expression-simplifier-calculator table {
width: 100%;
border-collapse: collapse;
min-width: 420px;
}#cd-expression-simplifier-calculator th,
#cd-expression-simplifier-calculator td {
border-bottom: 1px solid var(–cd-esc-border);
text-align: left;
padding: 9px;
vertical-align: top;
}#cd-expression-simplifier-calculator th {
background: var(–cd-esc-soft);
}#cd-expression-simplifier-calculator .cd-esc-section {
border-top: 1px solid var(–cd-esc-border);
padding: 24px 0;
}#cd-expression-simplifier-calculator .cd-esc-section ul {
margin: 0 0 0 20px;
padding: 0;
}#cd-expression-simplifier-calculator .cd-esc-section li {
margin-bottom: 8px;
}#cd-expression-simplifier-calculator .cd-esc-formula,
#cd-expression-simplifier-calculator .cd-esc-example {
background: var(–cd-esc-soft);
border: 1px solid var(–cd-esc-border);
border-radius: 10px;
padding: 12px;
}#cd-expression-simplifier-calculator .cd-esc-formula p:last-child {
margin-bottom: 0;
}#cd-expression-simplifier-calculator .cd-esc-example {
font-weight: 800;
overflow-wrap: anywhere;
}#cd-expression-simplifier-calculator details {
border: 1px solid var(–cd-esc-border);
border-radius: 10px;
padding: 12px 14px;
margin-bottom: 10px;
background: #ffffff;
}#cd-expression-simplifier-calculator summary {
cursor: pointer;
font-weight: 800;
}#cd-expression-simplifier-calculator details p {
margin-top: 10px;
margin-bottom: 0;
}@media (max-width: 720px) {
#cd-expression-simplifier-calculator .cd-esc-tool {
padding: 16px;
border-radius: 12px;
}#cd-expression-simplifier-calculator .cd-esc-grid {
grid-template-columns: 1fr;
gap: 0;
}#cd-expression-simplifier-calculator .cd-esc-buttons button,
#cd-expression-simplifier-calculator .cd-esc-presets button {
width: 100%;
}
}(function () {
function cdEscReady(fn) {
if (document.readyState === “loading”) {
document.addEventListener(“DOMContentLoaded”, fn);
} else {
fn();
}
}cdEscReady(function () {
var root = document.getElementById(“cd-expression-simplifier-calculator”);
if (!root) {
return;
}var input = document.getElementById(“cd-esc-expression”);
var decimalsSelect = document.getElementById(“cd-esc-decimals”);
var styleSelect = document.getElementById(“cd-esc-style”);
var calculateBtn = document.getElementById(“cd-esc-calculate”);
var copyBtn = document.getElementById(“cd-esc-copy”);
var clearBtn = document.getElementById(“cd-esc-clear”);
var errorBox = document.getElementById(“cd-esc-error”);
var mainResult = document.getElementById(“cd-esc-main-result”);
var noteBox = document.getElementById(“cd-esc-result-note”);
var stepsList = document.getElementById(“cd-esc-steps-list”);
var termsBox = document.getElementById(“cd-esc-terms-box”);
var lastCopyText = “”;function showError(message) {
errorBox.style.display = “block”;
errorBox.textContent = message;
}function clearError() {
errorBox.style.display = “none”;
errorBox.textContent = “”;
}function makePoly() {
return {};
}function copyPoly(poly) {
var out = {};
var keys = Object.keys(poly);
var i = 0;
while (i < keys.length) {
out[keys[i]] = poly[keys[i]];
i = i + 1;
}
return out;
}function cleanPoly(poly) {
var out = {};
var keys = Object.keys(poly);
var i = 0;
while (i 0.0000000001) {
out[key] = val;
}
i = i + 1;
}
return out;
}function constPoly(value) {
var poly = {};
if (Math.abs(value) > 0.0000000001) {
poly[“1”] = value;
}
return poly;
}function varPoly(name) {
var poly = {};
poly[name] = 1;
return poly;
}function parseKey(key) {
var map = {};
if (key === “1”) {
return map;
}
var parts = key.split(“*”);
var i = 0;
while (i < parts.length) {
var part = parts[i];
var powIndex = part.indexOf("^");
if (powIndex === -1) {
map[part] = 1;
} else {
var name = part.slice(0, powIndex);
var power = parseInt(part.slice(powIndex + 1), 10);
map[name] = power;
}
i = i + 1;
}
return map;
}function makeKey(map) {
var vars = Object.keys(map).sort();
var pieces = [];
var i = 0;
while (i 0) {
if (power === 1) {
pieces.push(name);
} else {
pieces.push(name + “^” + power);
}
}
i = i + 1;
}
if (pieces.length === 0) {
return “1”;
}
return pieces.join(“*”);
}function addKeys(a, b) {
var mapA = parseKey(a);
var mapB = parseKey(b);
var names = Object.keys(mapB);
var i = 0;
while (i < names.length) {
var name = names[i];
if (mapA[name]) {
mapA[name] = mapA[name] + mapB[name];
} else {
mapA[name] = mapB[name];
}
i = i + 1;
}
return makeKey(mapA);
}function addPoly(a, b) {
var out = copyPoly(a);
var keys = Object.keys(b);
var i = 0;
while (i < keys.length) {
var key = keys[i];
if (out[key]) {
out[key] = out[key] + b[key];
} else {
out[key] = b[key];
}
i = i + 1;
}
return cleanPoly(out);
}function negPoly(poly) {
var out = {};
var keys = Object.keys(poly);
var i = 0;
while (i < keys.length) {
out[keys[i]] = -poly[keys[i]];
i = i + 1;
}
return cleanPoly(out);
}function subPoly(a, b) {
return addPoly(a, negPoly(b));
}function mulPoly(a, b) {
var out = {};
var keysA = Object.keys(a);
var keysB = Object.keys(b);
var i = 0;
while (i < keysA.length) {
var j = 0;
while (j 120) {
throw new Error(“This expression expands into too many terms(out for this page calculator.”);
}
return out;
}function getConstant(poly) {
var keys = Object.keys(poly);
if (keys.length === 0) {
return 0;
}
if (keys.length === 1) {
if (Object.prototype.hasOwnProperty.call(poly, “1”)) {
return poly[“1”];
}
}
return null;
}function divPoly(a, b) {
var divisor = getConstant(b);
if (divisor === null) {
throw new Error(“Division is only supported when the divisor is a number.”);
}
if (Math.abs(divisor) < 0.0000000001) {
throw new Error("Division by zero is not allowed.");
}
var out = {};
var keys = Object.keys(a);
var i = 0;
while (i < keys.length) {
out[keys[i]] = a[keys[i]] / divisor;
i = i + 1;
}
return cleanPoly(out);
}function powPoly(poly, power) {
if (power 6) {
throw new Error(“For readability, exponents above 6 are not expanded by this calculator.”);
}
var out = constPoly(1);
var i = 0;
while (i < power) {
out = mulPoly(out, poly);
i = i + 1;
}
return out;
}function tokenize(text) {
var tokens = [];
var i = 0;
while (i < text.length) {
var ch = text.charAt(i);
if (/\s/.test(ch)) {
i = i + 1;
} else if ("+-*/^()".indexOf(ch) !== -1) {
tokens.push({ type: "op", value: ch });
i = i + 1;
} else if (/[0-9.]/.test(ch)) {
var start = i;
var dots = 0;
while (i 1) {
throw new Error(“A number can contain only one decimal point.”);
}
var numText = text.slice(start, i);
if (numText === “.”) {
throw new Error(“Please enter a valid number.”);
}
var value = Number(numText);
if (!Number.isFinite(value)) {
throw new Error(“Please enter a valid number.”);
}
tokens.push({ type: “number”, value: value });
} else if (/[a-zA-Z]/.test(ch)) {
tokens.push({ type: “var”, value: ch.toLowerCase() });
i = i + 1;
} else {
throw new Error(“Unsupported character found: ” + ch);
}
}
return tokens;
}function Parser(tokens) {
this.tokens = tokens;
this.pos = 0;
}Parser.prototype.peek = function () {
return this.tokens[this.pos];
};Parser.prototype.next = function () {
var token = this.tokens[this.pos];
this.pos = this.pos + 1;
return token;
};Parser.prototype.isStartOfFactor = function (token) {
if (!token) {
return false;
}
if (token.type === “number”) {
return true;
}
if (token.type === “var”) {
return true;
}
if (token.type === “op”) {
if (token.value === “(“) {
return true;
}
}
return false;
};Parser.prototype.parseExpression = function () {
var node = this.parseTerm();
while (this.peek()) {
var token = this.peek();
if (token.type === “op”) {
if (token.value === “+”) {
this.next();
node = addPoly(node, this.parseTerm());
} else if (token.value === “-“) {
this.next();
node = subPoly(node, this.parseTerm());
} else {
break;
}
} else {
break;
}
}
return node;
};Parser.prototype.parseTerm = function () {
var node = this.parseFactor();
while (this.peek()) {
var token = this.peek();
if (token.type === “op”) {
if (token.value === “*”) {
this.next();
node = mulPoly(node, this.parseFactor());
} else if (token.value === “/”) {
this.next();
node = divPoly(node, this.parseFactor());
} else if (token.value === “(“) {
node = mulPoly(node, this.parseFactor());
} else {
break;
}
} else if (this.isStartOfFactor(token)) {
node = mulPoly(node, this.parseFactor());
} else {
break;
}
}
return node;
};Parser.prototype.parseFactor = function () {
var token = this.peek();
if (token) {
if (token.type === “op”) {
if (token.value === “+”) {
this.next();
return this.parseFactor();
}
if (token.value === “-“) {
this.next();
return negPoly(this.parseFactor());
}
}
}var node = this.parsePrimary();
var nextToken = this.peek();
if (nextToken) {
if (nextToken.type === “op”) {
if (nextToken.value === “^”) {
this.next();
var expToken = this.next();
if (!expToken) {
throw new Error(“Missing exponent after ^.”);
}
if (expToken.type !== “number”) {
throw new Error(“Exponent must be a nonnegative integer.”);
}
if (Math.floor(expToken.value) !== expToken.value) {
throw new Error(“Exponent must be a nonnegative integer.”);
}
node = powPoly(node, expToken.value);
}
}
}
return node;
};Parser.prototype.parsePrimary = function () {
var token = this.next();
if (!token) {
throw new Error(“The expression ended too early.”);
}
if (token.type === “number”) {
return constPoly(token.value);
}
if (token.type === “var”) {
return varPoly(token.value);
}
if (token.type === “op”) {
if (token.value === “(“) {
var node = this.parseExpression();
var closeToken = this.next();
if (!closeToken) {
throw new Error(“Missing closing parenthesis.”);
}
if (closeToken.value !== “)”) {
throw new Error(“Missing closing parenthesis.”);
}
return node;
}
}
throw new Error(“Unexpected symbol: ” + token.value);
};function parseExpression(text) {
var tokens = tokenize(text);
if (tokens.length === 0) {
throw new Error(“Please enter an expression.”);
}
var parser = new Parser(tokens);
var poly = parser.parseExpression();
if (parser.pos < tokens.length) {
throw new Error("Unexpected extra input near: " + tokens[parser.pos].value);
}
return cleanPoly(poly);
}function degreeOfKey(key) {
if (key === "1") {
return 0;
}
var map = parseKey(key);
var names = Object.keys(map);
var total = 0;
var i = 0;
while (i < names.length) {
total = total + map[names[i]];
i = i + 1;
}
return total;
}function sortedKeys(poly) {
var keys = Object.keys(poly);
keys.sort(function (a, b) {
if (a === "1") {
return 1;
}
if (b === "1") {
return -1;
}
var da = degreeOfKey(a);
var db = degreeOfKey(b);
if (da !== db) {
return db – da;
}
if (a
b) {
return 1;
}
return 0;
});
return keys;
}function formatNumber(value, decimals) {
var factor = Math.pow(10, decimals);
var rounded = Math.round(value * factor) / factor;
if (Math.abs(rounded) 0) {
while (text.charAt(text.length – 1) === “0”) {
text = text.slice(0, -1);
}
if (text.charAt(text.length – 1) === “.”) {
text = text.slice(0, -1);
}
}
if (text === “-0”) {
text = “0”;
}
return text;
}function keyToText(key, spaced) {
if (key === “1”) {
return “”;
}
if (spaced) {
return key.replace(/\*/g, ” “);
}
return key.replace(/\*/g, “”);
}function polyToString(poly, decimals, spaced) {
var keys = sortedKeys(poly);
if (keys.length === 0) {
return “0”;
}
var pieces = [];
var i = 0;
while (i < keys.length) {
var key = keys[i];
var coef = poly[key];
var absCoef = Math.abs(coef);
var sign = coef < 0 ? "-" : "+";
var variableText = keyToText(key, spaced);
var coefText = formatNumber(absCoef, decimals);
var body = "";if (key === "1") {
body = coefText;
} else {
if (Math.abs(absCoef – 1) < 0.0000000001) {
body = variableText;
} else {
if (spaced) {
body = coefText + " " + variableText;
} else {
body = coefText + variableText;
}
}
}if (pieces.length === 0) {
if (sign === "-") {
pieces.push("-" + body);
} else {
pieces.push(body);
}
} else {
pieces.push(" " + sign + " " + body);
}
i = i + 1;
}
return pieces.join("");
}function renderTerms(poly, decimals) {
var keys = sortedKeys(poly);
if (keys.length === 0) {
return "All terms cancel out, so the expression simplifies to 0.
“;
}
var html = “
| Variable part | Combined coefficient | Term |
“;
var i = 0;
while (i < keys.length) {
var key = keys[i];
var variablePart = key === "1" ? "constant" : key;
var coef = formatNumber(poly[key], decimals);
var termText = polyToString((function () {
var temp = {};
temp[key] = poly[key];
return temp;
})(), decimals, true);
html = html + "| ” + variablePart + “ | ” + coef + “ | ” + termText + “ |
“;
i = i + 1;
}
html = html + “
“;
return html;
}function setSteps(items) {
stepsList.innerHTML = “”;
var i = 0;
while (i < items.length) {
var li = document.createElement("li");
li.textContent = items[i];
stepsList.appendChild(li);
i = i + 1;
}
}function simplifyNow() {
try {
clearError();
var raw = input.value.trim();
var decimals = parseInt(decimalsSelect.value, 10);
var spaced = styleSelect.value === "spaced";
var poly = parseExpression(raw);
var result = polyToString(poly, decimals, spaced);mainResult.textContent = result;
noteBox.textContent = "Equivalent simplified expression. Coefficients are shown with up to " + decimals + " decimal places.";
termsBox.innerHTML = renderTerms(poly, decimals);
setSteps([
"Read the expression as a polynomial expression.",
"Apply signs, multiplication, division by constants, powers, and parentheses where supported.",
"Group terms with the same variable part and exponent pattern.",
"Add the coefficients of each like-term group.",
"Write the simplified expression in standard order."
]);
lastCopyText = "Simplified result: " + result;
} catch (err) {
showError(err.message);
mainResult.textContent = "-";
noteBox.textContent = "Please correct the expression and try again.";
termsBox.textContent = "No terms available.";
setSteps([]);
lastCopyText = "";
}
}calculateBtn.addEventListener("click", simplifyNow);copyBtn.addEventListener("click", function () {
if (lastCopyText === "") {
showError("There is no result to copy yet.");
return;
}
if (navigator.clipboard) {
navigator.clipboard.writeText(lastCopyText).then(function () {
noteBox.textContent = "Result copied.";
}).catch(function () {
showError("Copy failed. You can select the result manually.");
});
} else {
showError("Clipboard copy is not available in this browser.");
}
});clearBtn.addEventListener("click", function () {
input.value = "";
clearError();
mainResult.textContent = "-";
noteBox.textContent = "Enter an expression and click simplify.";
termsBox.textContent = "No terms yet.";
setSteps([]);
lastCopyText = "";
input.focus();
});var presetButtons = root.querySelectorAll("[data-cd-esc-preset]");
var p = 0;
while (p < presetButtons.length) {
presetButtons[p].addEventListener("click", function () {
input.value = this.getAttribute("data-cd-esc-preset");
simplifyNow();
});
p = p + 1;
}input.addEventListener("keydown", function (event) {
if (event.key === "Enter") {
event.preventDefault();
simplifyNow();
}
});decimalsSelect.addEventListener("change", simplifyNow);
styleSelect.addEventListener("change", simplifyNow);simplifyNow();
});
})();