Skill: decimals-add-subtract
Decimal Adder with Alignment
Enter two decimals and see them lined up point-under-point, padded with zeros, and added column by column.
Decimal adder with alignment
Remember
Line up the decimal points — that is the whole rule. Pad with zeros so every column has a digit, then add or subtract like whole numbers.
/* == PURE (tested by test_tool.js) == */
function tDecParse(s){
s = String(s).trim();
var m = /^(-?)(\d*)(?:\.(\d*))?$/.exec(s);
if (!m || !(m[2] !== '' || !(m[3] === '' || m[3] === undefined))) return { ok: false };
var neg = m[1] === '-', intp = m[2] === '' ? '0' : m[2], frac = m[3] || '';
frac = (frac + '000').slice(0, 3);
var mil = parseInt(intp, 10) * 1000 + parseInt(frac, 10);
return { ok: true, mil: neg ? -mil : mil };
}
function tDecAdd(a, b){
var A = tDecParse(a), B = tDecParse(b);
if (!A.ok || !B.ok) return { ok: false, err: 'Enter numbers like 2.45.' };
var sum = A.mil + B.mil;
var neg = sum < 0, v = Math.abs(sum);
var intp = Math.floor(v / 1000), frac = v % 1000;
var fs = ('00' + frac).slice(-3).replace(/0+$/, '');
return { ok: true, aMil: A.mil, bMil: B.mil, sumMil: sum,
display: (neg ? '-' : '') + intp + (fs ? '.' + fs : '') };
}
function tDecSub(a, b){
var B = tDecParse(b);
if (!B.ok) return { ok: false };
var bMil = B.mil;
B.mil = -B.mil;
var A = tDecParse(a);
if (!A.ok) return { ok: false, err: 'Enter numbers like 5.2.' };
var sum = A.mil + B.mil;
var neg = sum < 0, v = Math.abs(sum);
var intp = Math.floor(v / 1000), frac = v % 1000;
var fs = ('00' + frac).slice(-3).replace(/0+$/, '');
return { ok: true, aMil: A.mil, bMil: bMil, sumMil: sum,
display: (neg ? '-' : '') + intp + (fs ? '.' + fs : '') };
}
/* == /PURE == */
/* == PURE (tested by test_tool.js) == */ function tDecParse(s){ s = String(s).trim(); var m = /^(-?)(\d*)(?:\.(\d*))?$/.exec(s); if (!m || !(m[2] !== '' || !(m[3] === '' || m[3] === undefined))) return { ok: false }; var neg = m[1] === '-', intp = m[2] === '' ? '0' : m[2], frac = m[3] || ''; frac = (frac + '000').slice(0, 3); var mil = parseInt(intp, 10) * 1000 + parseInt(frac, 10); return { ok: true, mil: neg ? -mil : mil }; } function tDecAdd(a, b){ var A = tDecParse(a), B = tDecParse(b); if (!A.ok || !B.ok) return { ok: false, err: 'Enter numbers like 2.45.' }; var sum = A.mil + B.mil; var neg = sum < 0, v = Math.abs(sum); var intp = Math.floor(v / 1000), frac = v % 1000; var fs = ('00' + frac).slice(-3).replace(/0+$/, ''); return { ok: true, aMil: A.mil, bMil: B.mil, sumMil: sum, display: (neg ? '-' : '') + intp + (fs ? '.' + fs : '') }; } function tDecSub(a, b){ var B = tDecParse(b); if (!B.ok) return { ok: false }; var bMil = B.mil; B.mil = -B.mil; var A = tDecParse(a); if (!A.ok) return { ok: false, err: 'Enter numbers like 5.2.' }; var sum = A.mil + B.mil; var neg = sum < 0, v = Math.abs(sum); var intp = Math.floor(v / 1000), frac = v % 1000; var fs = ('00' + frac).slice(-3).replace(/0+$/, ''); return { ok: true, aMil: A.mil, bMil: bMil, sumMil: sum, display: (neg ? '-' : '') + intp + (fs ? '.' + fs : '') }; } /* == /PURE == */
(function(){ 'use strict'; function $(id){ return document.getElementById(id); } function pad3(mil){ var neg = mil < 0, v = Math.abs(mil); var s = Math.floor(v / 1000) + '.' + ('00' + (v % 1000)).slice(-3); return (neg ? '-' : '') + s; } function render(){ var a = $('inA').value, b = $('inB').value, op = $('opSel').value; var out = $('toolOut'); var r = op === '+' ? tDecAdd(a, b) : tDecSub(a, b); if (!r.ok){ out.innerHTML = '
' + r.err + '
'; return; } var sym = op === '+' ? '+' : '−'; var h = '
' +
pad3(r.aMil) + '
' + sym + ' ' + pad3(r.bMil) + '
' +
'' + pad3(r.sumMil) + '
'; h += '
Answer: ' + r.display + '
'; out.innerHTML = h; } $('calcBtn').addEventListener('click', render); render(); })();