@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
75 lines (64 loc) • 2.72 kB
JavaScript
import { magnitude_prefix_index, MAGNITUDE_PREFIXES, MAGNITUDE_SCALES } from "./magnitude_prefix.js";
import { unit_matrix_to_string } from "./unit_matrix_to_string.js";
/**
* Trim trailing zeros (and a trailing decimal point) from a number string produced by
* {@link Number.prototype.toFixed}, so that `1.300` becomes `1.3` and `7.000` becomes `7`.
*
* @param {string} s
* @returns {string}
*/
function trim_trailing_zeros(s) {
if (s.indexOf('.') === -1) {
return s;
}
let end = s.length;
while (end > 0 && s.charCodeAt(end - 1) === 48 /* '0' */) {
end--;
}
if (end > 0 && s.charCodeAt(end - 1) === 46 /* '.' */) {
end--;
}
return s.substring(0, end);
}
/**
* Format a numeric value paired with a {@link UnitMatrix} into a compact human-readable string
* such as `1.3 km/s`, `2.5 N`, or `7 m`.
*
* The SI prefix (k, M, m, µ, ...) that brings the magnitude of `value` closest to `[1, 1000)` is
* selected, then prepended to the unit string. Trailing zeros in the numeric portion are removed.
*
* Edge cases:
* - dimensionless matrices output just the numeric portion plus a prefix (`1.5k`)
* - `0` and non-finite values are reported as-is, with no prefix
* - the unit and the value are separated by a single space when a unit symbol is present
*
* Optional named-unit recognition: when `named_units` is provided, the unit portion is rendered
* via {@link unit_matrix_to_string} using that registry — so e.g. `1300 V` can be produced
* directly instead of `1.3 kkg·m^2/s^3·A`.
*
* @param {number} value Numeric magnitude in the unit's base form (e.g. 1300 for 1300 m/s).
* @param {UnitMatrix} unit_matrix
* @param {number} [precision=3] Maximum number of digits after the decimal point.
* @param {NamedUnit[]} [named_units] Optional registry of compound-unit symbols.
* @param {NamedUnit[]} [dimension_units] Optional override for the per-dimension {@link NamedUnit} mapping; defaults to {@link UNIT_DIMENSION_MAPPING}.
* @returns {string}
*/
export function format_quantity(
value,
unit_matrix,
precision = 3,
named_units = undefined,
dimension_units = undefined
) {
const unit_string = unit_matrix_to_string(unit_matrix, named_units, dimension_units);
const index = magnitude_prefix_index(value);
const prefix = MAGNITUDE_PREFIXES[index];
const scale = MAGNITUDE_SCALES[index];
const scaled = value / scale;
const number_string = trim_trailing_zeros(scaled.toFixed(precision));
if (unit_string === '') {
// Dimensionless: number and prefix only ("1.5k", "0").
return number_string + prefix;
}
return number_string + ' ' + prefix + unit_string;
}