Skill: integer-operations
Integer Operations Calculator
Three tools in one: add and subtract on a visual number line, multiply and divide with the sign rule explained, or evaluate multi-step expressions. Every answer comes with the full working shown step by step.
1 Calculator
Pick a tool below. Nothing is hidden — every answer shows each step.
Add or subtract with a number-line walk
Enter two integers. The calculator walks the number line and shows the landing point.
Multiply or divide with the sign rule
Enter two integers. The calculator applies “same → positive, different → negative” and shows why.
Multi-step expressions, left to right
Enter three integers and two operations. The calculator works left to right, one step at a time.
"use strict"; /* Integer tool page wiring: tabs + three calculators (pure math in IntegerTool). */ (function () { var T = window.IntegerTool; function el(id) { return document.getElementById(id); } function esc(s) { return String(s).replace(/\x26/g, "&").replace(/" + s + "
"; }).join(""); } function readInt(id) { return T.parseIntStrict(el(id).value); }
/* --- Panel 1: add/subtract walk --- */ function drawWalk(a, move, landing, lo, hi) { var W = 760, H = 120, padL = 40, padR = 40; function X(v) { return padL + (v - lo) / (hi - lo) * (W - padL - padR); } var s = ""; s += '"; return s; } el("calc1").addEventListener("click", function () { showErr("err1", ""); var a = readInt("inA"), b = readInt("inB"); if (a === null || b === null) { showErr("err1", "Please enter both numbers as integers (like -7 or 4)."); el("res1").classList.remove("show"); return; } var op = el("op1").value; var r = T.addSub(a, op, b); if (r.error) { showErr("err1", r.error); el("res1").classList.remove("show"); return; } el("ans1").innerHTML = "Landing: " + esc(r.landing) + ""; renderSteps("steps1", r.steps); el("walk1").innerHTML = drawWalk(r.start, r.move, r.landing, r.lo, r.hi); el("res1").classList.add("show"); });
/* --- Panel 2: multiply/divide --- */ el("calc2").addEventListener("click", function () { showErr("err2", ""); var a = readInt("inC"), b = readInt("inD"); if (a === null || b === null) { showErr("err2", "Please enter both numbers as integers (like -6 or 7)."); el("res2").classList.remove("show"); return; } var op = el("op2").value; var r = T.mulDiv(a, op, b); if (r.error) { showErr("err2", r.error); el("res2").classList.remove("show"); return; } var badge = r.sign === "positive" ? 'POSITIVE' : (r.sign === "negative" ? 'NEGATIVE' : ""); el("ans2").innerHTML = "Answer: " + esc(r.resultText) + "" + badge; renderSteps("steps2", r.steps); el("res2").classList.add("show"); });
/* --- Panel 3: multi-step --- */ el("calc3").addEventListener("click", function () { showErr("err3", ""); var a = readInt("inE"), b = readInt("inF"), c = readInt("inG"); if (a === null || b === null || c === null) { showErr("err3", "Please enter all three numbers as integers."); el("res3").classList.remove("show"); return; } var r = T.multiStep(a, el("op3a").value, b, el("op3b").value, c); if (r.error) { showErr("err3", r.error); el("res3").classList.remove("show"); return; } el("ans3").innerHTML = "Answer: " + esc(r.resultText) + ""; renderSteps("steps3", r.steps); el("res3").classList.add("show"); }); })();
/* ============================================================ Integer Operations Tool — pure computation core (no DOM). UMD: required by node tests as a module, inlined into tool.html as window.IntegerTool. ============================================================ */ (function (root, factory) { 'use strict'; var api = factory(); if (typeof module === 'undefined') { root.IntegerTool = api; } else { module.exports = api; } })(typeof self !== 'undefined' ? self : this, function () { 'use strict';
var MINUS = '\u2212';
function fmtI(n) { return String(n).replace(/-/g, MINUS); }
function paren(n) { return n < 0 ? '(' + fmtI(n) + ')' : String(n); }
function parseIntStrict(raw) {
var s = String(raw).replace(/\u2212/g, '-').replace(/[\s,]+/g, '');
if (!/^[+-]?\d+$/.test(s)) return null;
var v = parseInt(s, 10);
return isFinite(v) ? v : null;
}
/* Tab 1: add/subtract with number-line walk.
Returns { start, move, landing, steps[], lo, hi } or { error }. */
function addSub(a, op, b) {
var opOk1 = (op === '+' || op === '\u2212' || op === '-');
if (!opOk1) return { error: 'Choose + or \u2212.' };
var move = (op === '+') ? b : -b;
var landing = a + move;
var lo = Math.min(a, landing) - 3, hi = Math.max(a, landing) + 3;
var steps = [];
steps.push('Start at ' + fmtI(a) + ' on the number line.');
if (move === 0) {
steps.push('The move is 0, so you stay exactly where you are.');
} else {
var dirWord = move > 0 ? 'right' : 'left';
steps.push((op === '+' ? 'Adding ' + paren(b) : 'Subtracting ' + b) +
' means walking ' + Math.abs(move) + ' step' + (Math.abs(move) === 1 ? '' : 's') +
' ' + dirWord + '.');
var crossDown = !( !(a < 0) || !(landing > 0) );
var crossUp = !( !(a > 0) || !(landing < 0) );
if (crossDown || crossUp || landing === 0) {
steps.push('Notice the walk crosses zero \u2014 keep counting past 0 into the ' +
(landing < 0 ? 'negatives' : 'positives') + '.');
}
}
steps.push('Landing point: ' + fmtI(a) + (op === '+' ? ' + ' : ' \u2212 ') + paren(b) +
' = ' + fmtI(landing) + '.');
return { start: a, move: move, landing: landing, steps: steps, lo: lo, hi: hi };
}
/* Tab 2: multiply/divide with the sign rule.
Returns { a, b, op, sign, magnitude, result, resultText, steps[] } or { error }. */
function mulDiv(a, op, b) {
var opOk2 = (op === '\u00D7' || op === '*' || op === '\u00F7' || op === '/');
if (!opOk2)
return { error: 'Choose \u00D7 or \u00F7.' };
var isMul = (op === '\u00D7' || op === '*');
if (!isMul) { if (b === 0) return { error: 'Division by zero is not allowed.' }; }
var steps = [];
var sign, result, resultText;
if (a === 0 || b === 0) {
sign = 'zero';
result = 0; resultText = '0';
steps.push('One of the numbers is 0, so the answer is 0 (no sign rule needed).');
} else {
var same = (a < 0) === (b < 0);
sign = same ? 'positive' : 'negative';
steps.push('Step 1 \u2014 the sign: ' + paren(a) + ' and ' + paren(b) +
' have ' + (same ? 'the SAME sign' : 'DIFFERENT signs') + ' \u2192 the answer is ' + sign + '.');
if (isMul) {
var mag = Math.abs(a) * Math.abs(b);
steps.push('Step 2 \u2014 the size: ' + Math.abs(a) + ' \u00D7 ' + Math.abs(b) + ' = ' + mag + '.');
result = same ? mag : -mag;
resultText = fmtI(result);
} else {
var top = Math.abs(a), bot = Math.abs(b);
if (top % bot === 0) {
var q = top / bot;
steps.push('Step 2 \u2014 the size: ' + top + ' \u00F7 ' + bot + ' = ' + q + ' exactly.');
result = same ? q : -q;
resultText = fmtI(result);
} else {
var dec = top / bot;
var rounded = Math.round(dec * 10000) / 10000;
steps.push('Step 2 \u2014 the size: ' + top + ' \u00F7 ' + bot + ' = ' + rounded + ' (not a whole number).');
result = same ? rounded : -rounded;
resultText = fmtI(same ? rounded : -rounded);
}
}
steps.push('Answer: ' + resultText + '.');
}
return { a: a, b: b, op: isMul ? '\u00D7' : '\u00F7', sign: sign, result: result, resultText: resultText, steps: steps };
}
/* Tab 3: multi-step evaluation, left to right.
Returns { steps[], result } or { error }. */
function multiStep(a, op1, b, op2, c) {
var valid = { '+': 1, '\u2212': 1, '-': 1, '\u00D7': 1, '*': 1, '\u00F7': 1, '/': 1 };
if (!valid[op1] || !valid[op2]) return { error: 'Choose an operation for each step.' };
function norm(o) {
if (o === '-') return '\u2212';
if (o === '*') return '\u00D7';
if (o === '/') return '\u00F7';
return o;
}
op1 = norm(op1); op2 = norm(op2);
function apply(x, o, y) {
if (o === '+') return x + y;
if (o === '\u2212') return x - y;
if (o === '\u00D7') return x * y;
if (y === 0) return NaN;
return x / y;
}
var mid = apply(a, op1, b);
if (!isFinite(mid)) return { error: 'Division by zero is not allowed.' };
var result = apply(mid, op2, c);
if (!isFinite(result)) return { error: 'Division by zero is not allowed.' };
function show(v) { return (Math.round(v * 10000) / 10000).toString().replace(/-/g, MINUS); }
var steps = [];
steps.push('Work strictly left to right.');
steps.push('First: ' + fmtI(a) + ' ' + op1 + ' ' + paren(b) + ' = ' + show(mid) + '.');
steps.push('Then: ' + show(mid) + ' ' + op2 + ' ' + paren(c) + ' = ' + show(result) + '.');
return { steps: steps, result: result, resultText: show(result) };
}
return {
addSub: addSub,
mulDiv: mulDiv,
multiStep: multiStep,
parseIntStrict: parseIntStrict,
fmtI: fmtI
};
});
"use strict"; /* Integer tool page wiring: tabs + three calculators (pure math in IntegerTool). */ (function () { var T = window.IntegerTool; function el(id) { return document.getElementById(id); } function esc(s) { return String(s).replace(/\x26/g, "&").replace(/" + s + "
"; }).join(""); } function readInt(id) { return T.parseIntStrict(el(id).value); }
/* --- Panel 1: add/subtract walk --- */ function drawWalk(a, move, landing, lo, hi) { var W = 760, H = 120, padL = 40, padR = 40; function X(v) { return padL + (v - lo) / (hi - lo) * (W - padL - padR); } var s = ""; s += '"; return s; } el("calc1").addEventListener("click", function () { showErr("err1", ""); var a = readInt("inA"), b = readInt("inB"); if (a === null || b === null) { showErr("err1", "Please enter both numbers as integers (like -7 or 4)."); el("res1").classList.remove("show"); return; } var op = el("op1").value; var r = T.addSub(a, op, b); if (r.error) { showErr("err1", r.error); el("res1").classList.remove("show"); return; } el("ans1").innerHTML = "Landing: " + esc(r.landing) + ""; renderSteps("steps1", r.steps); el("walk1").innerHTML = drawWalk(r.start, r.move, r.landing, r.lo, r.hi); el("res1").classList.add("show"); });
/* --- Panel 2: multiply/divide --- */ el("calc2").addEventListener("click", function () { showErr("err2", ""); var a = readInt("inC"), b = readInt("inD"); if (a === null || b === null) { showErr("err2", "Please enter both numbers as integers (like -6 or 7)."); el("res2").classList.remove("show"); return; } var op = el("op2").value; var r = T.mulDiv(a, op, b); if (r.error) { showErr("err2", r.error); el("res2").classList.remove("show"); return; } var badge = r.sign === "positive" ? 'POSITIVE' : (r.sign === "negative" ? 'NEGATIVE' : ""); el("ans2").innerHTML = "Answer: " + esc(r.resultText) + "" + badge; renderSteps("steps2", r.steps); el("res2").classList.add("show"); });
/* --- Panel 3: multi-step --- */ el("calc3").addEventListener("click", function () { showErr("err3", ""); var a = readInt("inE"), b = readInt("inF"), c = readInt("inG"); if (a === null || b === null || c === null) { showErr("err3", "Please enter all three numbers as integers."); el("res3").classList.remove("show"); return; } var r = T.multiStep(a, el("op3a").value, b, el("op3b").value, c); if (r.error) { showErr("err3", r.error); el("res3").classList.remove("show"); return; } el("ans3").innerHTML = "Answer: " + esc(r.resultText) + ""; renderSteps("steps3", r.steps); el("res3").classList.add("show"); }); })();