UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

75 lines (64 loc) 2.72 kB
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; }