'use strict'; // speed-conversion.cjs -- METHOD DECK (X063), reversible speed unit conversion. // Factors are exact meters-per-second equivalents built from the NIST SP 811 exact length // definitions (mile = 1609.344 m, nautical mile = 1852 m, foot = 0.3048 m) over exact time units. function roundSig(x, sig) { if (x === 0) return { value: 0, decimals: 0 }; const neg = x < 0; const ax = Math.abs(x); let exp = Math.floor(Math.log10(ax)); let decimals = Math.max(sig - exp - 1, 0); let factor = Math.pow(10, decimals); let value = Math.round(ax * factor) / factor; const newExp = value === 0 ? exp : Math.floor(Math.log10(value)); if (newExp !== exp) { decimals = Math.max(sig - newExp - 1, 0); factor = Math.pow(10, decimals); value = Math.round(ax * factor) / factor; } return { value: neg ? -value : value, decimals }; } function fmt(x, decimals) { return x.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals }); } function fmtSig(x, sig) { const r = roundSig(x, sig); return fmt(r.value, r.decimals); } // Meters per second per 1 unit. const TO_MS = { m_s: 1, km_h: 1000 / 3600, mph: 1609.344 / 3600, knot: 1852 / 3600, ft_s: 0.3048, }; const UNITS = Object.keys(TO_MS); const DISPLAY = { m_s: 'm/s', km_h: 'km/h', mph: 'mph', knot: 'knot', ft_s: 'ft/s' }; module.exports = { slug: 'speed-conversion', title: 'Speed conversion', deck_category: 'units', description: 'Converts a speed between m/s, km/h, mph, knots, and ft/s using exact NIST SP 811 length and time definitions.', inputs: [ { name: 'value', type: 'number', unit: 'from_unit', required: true, description: 'The speed to convert' }, { name: 'from_unit', type: 'string', required: true, description: 'Unit of the input value', enum: UNITS }, { name: 'to_unit', type: 'string', required: true, description: 'Unit to convert into', enum: UNITS }, ], outputs: [ { name: 'result', unit: 'to_unit', description: 'The converted speed' } ], steps: [ 'Look up the exact meters-per-second equivalent of from_unit and of to_unit.', 'Convert the input to m/s: mps = value * ms_per(from_unit).', 'Convert m/s to the target unit: result = mps / ms_per(to_unit).', 'Round result to 6 significant figures.', ], constants: [ { name: 'm_s', value: 1, unit: 'm/s', source: 0 }, { name: 'km_h', value: 1000 / 3600, unit: 'm/s', source: 0 }, { name: 'mph', value: 1609.344 / 3600, unit: 'm/s', source: 0 }, { name: 'knot', value: 1852 / 3600, unit: 'm/s', source: 0 }, { name: 'ft_s', value: 0.3048, unit: 'm/s', source: 0 }, ], sources: [ { kind: 'standard', value: 'NIST Special Publication 811 (2008 edition), Appendix B.8: mile = 1609.344 m, international nautical mile = 1852 m, foot = 0.3048 m, all exact; combined with the exact SI hour (3600 s) and second.', title: 'Guide for the Use of the International System of Units (SI)', publisher: 'National Institute of Standards and Technology', retrieved_utc: '2026-09-30T19:29:48Z', note: 'km/h = 1000 m per 3600 s; mph = 1609.344 m per 3600 s; knot = 1852 m per 3600 s; all exact ratios.' }, ], disclaimer: null, questionText(inputs) { return `How fast is ${inputs.value} ${DISPLAY[inputs.from_unit]} in ${DISPLAY[inputs.to_unit]}?`; }, run(inputs) { const { value, from_unit, to_unit } = inputs || {}; if (typeof value !== 'number' || !isFinite(value)) throw new Error('value must be a finite number'); if (!TO_MS.hasOwnProperty(from_unit)) throw new Error('from_unit must be one of: ' + UNITS.join(', ')); if (!TO_MS.hasOwnProperty(to_unit)) throw new Error('to_unit must be one of: ' + UNITS.join(', ')); const mps = value * TO_MS[from_unit]; const result = mps / TO_MS[to_unit]; return { answer: `${fmtSig(result, 6)} ${DISPLAY[to_unit]}`, values: { result } }; }, examples: [ { name: 'worked example', inputs: { value: 100, from_unit: 'km_h', to_unit: 'mph' }, expected: { answer: '62.1371 mph' }, check: 'By hand: 100 km/h = 27.77778 m/s; 27.77778 / 0.44704 = 62.13712...; rounded to 6 significant figures is 62.1371.' }, { name: 'test vector: knot to km/h', inputs: { value: 1, from_unit: 'knot', to_unit: 'km_h' }, expected: { answer: '1.85200 km/h' }, check: 'By definition 1 knot = 1 nautical mile (1852 m) per hour = 1.852 km/h exactly.' }, { name: 'test vector: mph to ft/s', inputs: { value: 60, from_unit: 'mph', to_unit: 'ft_s' }, expected: { answer: '88.0000 ft/s' }, check: 'By hand: 60 mph = 60 * 0.44704 m/s = 26.8224 m/s; 26.8224 / 0.3048 = 88 exactly, matching the well-known 60 mph = 88 ft/s.' }, ], };