The problem: you typed 100 km/h into a converter and got three different mph values
You have a car speed: 100 km/h. You paste it into converter A and read 62.14 mph. Converter B says 62.137. Converter C says 62.1371192237. Three tools, three answers, same input. The difference isn't physics — it's rounding precision and the conversion path. Converter A rounded to 2 decimals. Converter B rounded to 3. Converter C kept full float64 precision. The honest move is a converter that stores the exact factor, does one multiply and one divide, and lets you pick the display precision — instead of chaining conversions through intermediate units that accumulate rounding error. 100 km/h is exactly 62.13711922373338 mph because 1 km/h = 0.6213711922373338 mph (the factor is 1609.344 / 3600, derived from the exact definitions of a meter, a mile, and a second). The rest is display.
Fastest path
Open the Speed Converter, type 100, pick km/h → mph, read the result.
Input: 100 km/h
→ m/s: 27.778 (the base unit — every conversion goes through here)
→ mph: 62.137 (100 × 0.62137119...)
→ kn: 53.996 (100 × 0.53995680...)
→ ft/s: 91.134 (100 × 0.91134442...)
→ Mach: 0.081 (27.778 / 343)
→ c: 9.27e-8 (27.778 / 299792458)
→ Beaufort: Force 5 (Fresh Breeze, 29-38 km/h) — no, 100 km/h is Force 8 (Gale)
→ Travel time for 100 km at 100 km/h: 1h 00m 00s
The tool took 100 km/h, multiplied by km/h's toBase factor (1/3.6) to get 27.778 m/s, then divided by each target unit's toBase factor to render all 23 units in parallel. The rest of this guide is why m/s is the base unit, why km/h is 1/3.6, why Mach is not a fixed number, why the Beaufort scale is a lookup table, and why travel time is one division.
The substance: one base unit, one multiply, one divide
m/s is the base unit and every conversion goes through it
The tool's units array has 23 entries across 5 categories (metric, imperial, nautical, scientific, fun). Each entry has a toBase field — the factor that converts one of that unit to meters per second. m/s itself has toBase: 1. km/h has toBase: 1 / 3.6. mph has toBase: 0.44704. Knots has toBase: 0.514444. Mach has toBase: 343. The speed of light has toBase: 299_792_458. Furlongs per fortnight has toBase: 1.66309e-4.
The conversion is two steps:
const mps = value * sourceUnit.toBase; // source → m/s
const result = mps / targetUnit.toBase; // m/s → target
There is no km/h-to-mph function, no knots-to-Mach function. Every conversion goes through m/s. This is the same pattern as the byte converter (everything through bytes) and the color converter (everything through RGB) — one base unit, many renderings. The advantage is that adding a new unit requires only one number (its toBase factor), not a conversion matrix of N×N entries. With 23 units, a full matrix would need 506 conversion functions; the base-unit approach needs 23 factors.
Where the factors come from
The factors are not arbitrary constants — each is derived from the physical definition of the unit. km/h is 1/3.6 because 1 kilometer = 1000 meters and 1 hour = 3600 seconds, so 1 km/h = 1000 m / 3600 s = 0.2778 m/s = 1/3.6 m/s. mph is 0.44704 because 1 mile = 1609.344 meters (the international mile, defined exactly in 1959) and 1 hour = 3600 s, so 1609.344 / 3600 = 0.44704. Knots is 0.514444 because 1 nautical mile = 1852 meters (defined exactly) and 1852 / 3600 = 0.514444. Feet per second is 0.3048 because 1 foot = 0.3048 meters (exact, since 1959). Mach is 343 because the speed of sound at sea level at 20°C is approximately 343 m/s — but that "approximately" is the catch (see below).
The furlongs-per-fortnight entry (toBase: 1.66309e-4) is the joke unit that proves the rule. 1 furlong = 201.168 meters (1/8 mile). 1 fortnight = 14 days = 1,209,600 seconds. 201.168 / 1,209,600 = 1.66309e-4. It's a real speed unit with a real factor — it's just absurd. The tool includes it in the "fun" category to make the point that any unit with a defined relationship to meters and seconds can be added to the array with one number.
Mach is not a fixed speed
The tool has three separate sound-speed entries: Mach (sea level, 20 C) at 343 m/s, Speed of sound (15 C) at 340.27 m/s, and Speed of sound (water) at 1480 m/s. These are three different numbers because the speed of sound depends on the medium and its temperature. In air at 20°C, sound travels at 343 m/s. In air at 15°C, it's 340.27 m/s — slower because colder air is denser. In water at 25°C, it's 1480 m/s — faster because water is incompressible compared to air. At altitude, say 10,000 m where the temperature is -50°C, the speed of sound drops to about 295 m/s. Mach 1 at 10,000 m is 295 m/s, not 343.
This is why the tool labels its Mach entry "sea level, 20 C" — it's telling you the assumption. If you're computing Mach for a cruise altitude, you need a different toBase factor. The tool doesn't adjust for altitude; it gives you the sea-level value and expects you to know the difference. A "Mach 0.85" aircraft speed is 0.85 × the local speed of sound, which varies with altitude. The tool's Mach conversion is a ballpark for sea-level reference, not a flight instrument.
The Beaufort scale is a lookup table, not a formula
The tool ships a beaufortScale array with 13 entries (force 0 through force 12). Each entry has a minKmh, maxKmh, a label (Calm, Light Air, Light Breeze, ... Hurricane), a sea condition, and a land condition. The getBeaufort(kmh) function does a linear scan:
beaufortScale.find(b => kmh >= b.minKmh && kmh <= b.maxKmh)
This is a discrete lookup, not a formula. The Beaufort scale was created in 1805 by Sir Francis Beaufort as an observation scale for sailors — force 0 is "smoke rises vertically," force 4 is "small waves, whitecaps," force 12 is "air filled with foam." The km/h ranges were added later by converting the original wind-effect observations to measured speeds. The ranges are uneven: force 0 is 0-1 km/h (1 km/h wide), force 5 is 29-38 km/h (10 km/h wide), force 12 is 118+ km/h (open-ended). The scale is logarithmic-ish because human perception of wind intensity is logarithmic — the difference between 20 and 30 km/h feels smaller than the difference between 80 and 90 km/h.
The tool renders the current Beaufort entry as a colored badge on the result banner, but only when kmh > 0 && kmh < 200. Above 200 km/h, you're in jet territory and the Beaufort scale is meaningless — it caps at hurricane (118+). The cap is a guard against rendering "Force 12" for a speed of light conversion.
formatValue and the precision tradeoff
The tool's formatValue(value, precision) function handles the display:
if (!isFinite(value)) return '—';
if (value === 0) return '0';
const abs = Math.abs(value);
if (abs < 1e-9 || abs >= 1e15) return value.toExponential(precision);
return value.toFixed(precision).replace(/\.?0+$/, '');
Three branches: non-finite returns an em-dash (division by zero, NaN). Very small (< 1e-9) or very large (>= 1e15) switches to exponential notation. Otherwise, toFixed(precision) with trailing zeros stripped. The precision selector offers 2, 4, 6, 8, or 10 decimals.
The branches exist because speed conversions span 17 orders of magnitude. 100 km/h in furlongs-per-fortnight is about 447,000 — a 6-digit number that toFixed(4) would render as 447000.0000. 100 km/h in the speed of light is 9.27e-8 — a number so small that toFixed(10) would render as 0.0000000927, which is readable but unwieldy. The exponential branch handles both extremes. The trailing-zero strip is cosmetic: 62.1400 becomes 62.14, 62.0000 becomes 62. The precision you pick is a display choice — the underlying conversion is always full float64.
Travel time is one division
The Travel Time Calculator tab takes a distance and uses the current speed to compute time:
const distM = travelDistUnit === 'km' ? dist * 1000 : travelDistUnit === 'mi' ? dist * 1609.34 : dist;
const seconds = distM / mps;
const totalMin = seconds / 60;
Distance converts to meters (km × 1000, mi × 1609.34, or meters as-is). Speed is already in m/s. Time in seconds = meters ÷ m/s. That's one division. The formatTime helper converts seconds to human-readable: under 1 minute shows seconds, under 24 hours shows Hh MMm SSs, over 24 hours shows Dd Hh MMm.
The "same distance at other speeds" comparison panel does the same division for five reference speeds (walking 5 km/h, cycling 25, driving 110, train 320, jet 900). The bar widths are proportional to 5 / speedKmh — the walking bar is always full (the baseline), the jet bar is tiny. This is a visual ratio, not a physics formula; it shows how much faster each mode is than walking.
Gotchas
- Every conversion goes through m/s. The tool has no unit-to-unit functions. Adding a new unit requires one
toBasefactor, not a matrix. If you're building your own converter, use the same pattern — a full 23×23 matrix is 506 functions; a base-unit approach is 23 factors. - Mach is temperature-dependent. The tool's Mach entry is 343 m/s (sea level, 20°C). At altitude in cold air, Mach 1 is slower (295 m/s at -50°C). At sea level in 40°C heat, it's faster (355 m/s). Don't use the tool's Mach conversion for flight instrumentation — use the local speed of sound.
- The speed of light is exact, not approximate. Since 1983, the meter is defined as the distance light travels in 1/299,792,458 of a second. The factor
299_792_458is exact by definition. Every other unit's factor is derived from physical measurements (the mile, the nautical mile) or exact definitions (the foot = 0.3048 m since 1959). - Knots and nautical miles per hour are the same unit. The tool has both (
knandnmi/h), both withtoBase: 0.514444. 1 knot is defined as 1 nautical mile per hour. They're synonyms, not different units — the tool lists both for search discoverability. - The Beaufort scale is a discrete lookup, not a continuous formula. Force 4 covers 20-28 km/h — 19 km/h is Force 3, 20 km/h is Force 4. The boundary is a hard cutoff in the
findpredicate. The scale is logarithmic-ish, not linear: the ranges get wider at higher forces. - formatValue strips trailing zeros.
62.1400becomes62.14. If you need exactly 4 decimal places (for a spec sheet), copy the value before the strip, or use the scientific-notation toggle which preserves precision. - The Beaufort badge caps at 200 km/h. Above 200 km/h, the badge doesn't render — you're in jet/rocket territory and the Beaufort scale (which tops out at hurricane, 118+ km/h) is meaningless. The tool's
kmh < 200guard prevents a "Force 12" label on a speed-of-light conversion. - Travel time assumes constant speed. The division
distance / speedis exact for constant speed. Real travel involves acceleration, deceleration, stops, and traffic. The tool's travel-time panel is a ballpark for planning, not a GPS ETA. - Precision doesn't change the underlying value. The float64 conversion is always full precision. The precision selector only changes display.
62.1371at precision 4 and62.14at precision 2 are the same number — the tool doesn't round the stored value, only the rendered string. - Furlongs per fortnight is real but absurd. 1 furlong = 201.168 m, 1 fortnight = 1,209,600 s, factor = 1.66309e-4. It's in the "fun" category. 100 km/h in furlongs/fortnight is about 447,000 — a number that triggers the exponential branch in
formatValueonly at the extremes. The unit exists to prove that any speed unit with a defined meter-and-second relationship can be added with one factor.
Summary
- m/s is the base unit. The tool's 23 units each have a
toBasefactor. Convert =value × source.toBase / target.toBase. One multiply, one divide. No chained conversions, no N×N matrix. Adding a unit requires one number, not a row of conversion functions. - The factors come from physical definitions. km/h is 1/3.6 (1000 m / 3600 s). mph is 0.44704 (1609.344 m / 3600 s). Knots is 0.514444 (1852 m / 3600 s). The speed of light is 299,792,458 — exact by definition of the meter since 1983. Furlongs per fortnight is 1.66309e-4 (201.168 m / 1,209,600 s).
- Mach is not a fixed speed. The tool's Mach entry is 343 m/s (sea level, 20°C). At altitude in cold air, Mach 1 is slower. In water, it's 1480 m/s. The tool has three separate sound-speed entries to make the medium and temperature dependence explicit.
- The Beaufort scale is a lookup table. 13 entries (force 0-12), each with a km/h range.
getBeaufort(kmh)does a linear scan for the matching range. It's an observation scale from 1805, not a formula. The ranges are uneven and logarithmic-ish. The badge caps at 200 km/h — above that, the scale is meaningless. - formatValue handles 17 orders of magnitude. Exponential notation for values < 1e-9 or >= 1e15.
toFixed(precision)with trailing zeros stripped otherwise. The precision selector (2/4/6/8/10 decimals) is a display choice — the underlying float64 is always full precision. - Travel time is one division. Distance in meters ÷ speed in m/s = seconds.
formatTimerenders as seconds,Hh MMm SSs, orDd Hh MMm. The "same distance at other speeds" panel does the same division for five reference speeds. The bar widths are visual ratios, not physics. - Convert at the Speed Converter; for distance conversions use Length Converter, for time unit conversions use Time Converter, and for temperature scales use Temperature Converter.