UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.

860 lines (755 loc) 32.4 kB
var util = require('../util/index'), number = util.number, string = util.string, isNumber = util.number.isNumber, isString = util.string.isString; /** * @constructor Unit * * A unit can be constructed in the following ways: * var a = new Unit(value, name); * var b = new Unit(null, name); * var c = Unit.parse(str); * * Example usage: * var a = new Unit(5, 'cm'); // 50 mm * var b = Unit.parse('23 kg'); // 23 kg * var c = math.in(a, new Unit(null, 'm'); // 0.05 m * * @param {Number} [value] A value like 5.2 * @param {String} [unit] A unit like "cm" or "inch" */ function Unit(value, name) { if (!(this instanceof Unit)) { throw new Error('Constructor must be called with the new operator'); } if (value != null && !isNumber(value)) { throw new TypeError('First parameter in Unit constructor must be a number'); } if (name != null && (!isString(name) || name == '')) { throw new TypeError('Second parameter in Unit constructor must be a string'); } if (name != null) { // find the unit and prefix from the string var res = _findUnit(name); if (!res) { throw new SyntaxError('Unknown unit "' + name + '"'); } this.unit = res.unit; this.prefix = res.prefix; } else { this.unit = UNIT_NONE; this.prefix = PREFIX_NONE; // link to a list with supported prefixes } if (value != null) { this.value = this._normalize(value); this.fixPrefix = false; // is set true by the methods Unit.in and math.in } else { this.value = null; this.fixPrefix = true; } } // private variables and functions for the Unit parser var text, index, c; function skipWhitespace() { while (c == ' ' || c == '\t') { next(); } } function isDigitDot (c) { return ((c >= '0' && c <= '9') || c == '.'); } function isDigit (c) { return ((c >= '0' && c <= '9')); } function next() { index++; c = text.charAt(index); } function revert(oldIndex) { index = oldIndex; c = text.charAt(index); } function parseNumber () { var number = ''; var oldIndex; oldIndex = index; if (c == '+') { next(); } else if (c == '-') { number += c; next(); } if (!isDigitDot(c)) { // a + or - must be followed by a digit revert(oldIndex); return null; } // get number, can have a single dot if (c == '.') { number += c; next(); if (!isDigit(c)) { // this is no legal number, it is just a dot revert(oldIndex); return null; } } else { while (isDigit(c)) { number += c; next(); } if (c == '.') { number += c; next(); } } while (isDigit(c)) { number += c; next(); } // check for exponential notation like "2.3e-4" or "1.23e50" if (c == 'E' || c == 'e') { number += c; next(); if (c == '+' || c == '-') { number += c; next(); } // Scientific notation MUST be followed by an exponent if (!isDigit(c)) { // this is no legal number, exponent is missing. revert(oldIndex); return null; } while (isDigit(c)) { number += c; next(); } } return number; } function parseUnit() { var unitName = ''; skipWhitespace(); while (c && c != ' ' && c != '\t') { unitName += c; next(); } return unitName || null; } /** * Parse a string into a unit. Returns null if the provided string does not * contain a valid unit. * @param {String} str A string like "5.2 inch", "4e2 kg" * @return {Unit | null} unit */ Unit.parse = function parse(str) { text = str; index = -1; c = ''; if (!isString(text)) { return null; } next(); skipWhitespace(); var value = parseNumber(); var name; if (value) { name = parseUnit(); next(); skipWhitespace(); if (c) { // garbage at the end. not good. return null; } if (value && name) { try { // constructor will throw an error when unit is not found return new Unit(Number(value), name); } catch (err) {} } } else { name = parseUnit(); next(); skipWhitespace(); if (c) { // garbage at the end. not good. return null; } if (name) { try { // constructor will throw an error when unit is not found return new Unit(null, name); } catch (err) {} } } return null; }; /** * Test whether value is of type Unit * @param {*} value * @return {Boolean} isUnit */ Unit.isUnit = function isUnit(value) { return (value instanceof Unit); }; /** * create a copy of this unit * @return {Unit} clone */ Unit.prototype.clone = function () { var clone = new Unit(); for (var p in this) { if (this.hasOwnProperty(p)) { clone[p] = this[p]; } } return clone; }; /** * Normalize a value, based on its currently set unit * @param {Number} value * @return {Number} normalized value * @private */ Unit.prototype._normalize = function(value) { return (value + this.unit.offset) * this.unit.value * this.prefix.value; }; /** * Unnormalize a value, based on its currently set unit * @param {Number} value * @param {Number} [prefixValue] Optional prefix value to be used * @return {Number} unnormalized value * @private */ Unit.prototype._unnormalize = function (value, prefixValue) { if (prefixValue == undefined) { return value / this.unit.value / this.prefix.value - this.unit.offset; } else { return value / this.unit.value / prefixValue - this.unit.offset; } }; /** * Find a unit from a string * @param {String} str A string like 'cm' or 'inch' * @returns {Object | null} result When found, an object with fields unit and * prefix is returned. Else, null is returned. * @private */ function _findUnit(str) { for (var name in UNITS) { if (UNITS.hasOwnProperty(name)) { if (string.endsWith(str, name) ) { var unit = UNITS[name]; var prefixLen = (str.length - name.length); var prefixName = str.substring(0, prefixLen); var prefix = unit.prefixes[prefixName]; if (prefix !== undefined) { // store unit, prefix, and value return { unit: unit, prefix: prefix }; } } } } return null; } /** * Test if the given expression is a unit. * The unit can have a prefix but cannot have a value. * @param {String} name A string to be tested whether it is a value less unit. * The unit can have prefix, like "cm" * @return {Boolean} true if the given string is a unit */ Unit.isValuelessUnit = function (name) { return (_findUnit(name) != null); }; /** * check if this unit has given base unit * @param {BASE_UNITS | undefined} base */ Unit.prototype.hasBase = function(base) { return (this.unit.base === base); }; /** * Check if this unit has a base equal to another base * @param {Unit} other * @return {Boolean} true if equal base */ Unit.prototype.equalBase = function(other) { return (this.unit.base === other.unit.base); }; /** * Check if this unit equals another unit * @param {Unit} other * @return {Boolean} true if both units are equal */ Unit.prototype.equals = function(other) { return (this.equalBase(other) && this.value == other.value); }; /** * Create a clone of this unit with a representation * @param {String | Unit} valuelessUnit A unit without value. Can have prefix, like "cm" * @returns {Unit} unit having fixed, specified unit */ Unit.prototype.to = function (valuelessUnit) { var other; if (isString(valuelessUnit)) { other = new Unit(null, valuelessUnit); if (!this.equalBase(other)) { throw new Error('Units do not match'); } other.value = this.value; return other; } else if (valuelessUnit instanceof Unit) { if (!this.equalBase(valuelessUnit)) { throw new Error('Units do not match'); } if (valuelessUnit.value != null) { throw new Error('Cannot convert to a unit with a value'); } other = valuelessUnit.clone(); other.value = this.value; other.fixPrefix = true; return other; } else { throw new Error('String or Unit expected as parameter'); } }; /** * Return the value of the unit when represented with given valueless unit * @param {String | Unit} valuelessUnit For example 'cm' or 'inch' * @return {Number} value */ Unit.prototype.toNumber = function (valuelessUnit) { var other = this.to(valuelessUnit); return other._unnormalize(other.value, other.prefix.value); }; /** * Get a string representation of the unit. * @return {String} */ Unit.prototype.toString = function toString() { return this.format(); }; /** * Get a string representation of the Unit, with optional formatting options. * @param {Object | Number | Function} [options] Formatting options. See * lib/util/number:format for a * description of the available * options. * @return {String} */ Unit.prototype.format = function format(options) { var value, str; if (!this.fixPrefix) { var bestPrefix = this._bestPrefix(); value = this._unnormalize(this.value, bestPrefix.value); str = number.format(value, options) + ' '; str += bestPrefix.name + this.unit.name; } else { value = this._unnormalize(this.value); str = (this.value != null) ? number.format(value, options) + ' ' : ''; str += this.prefix.name + this.unit.name; } return str; }; /** * Calculate the best prefix using current value. * @returns {Object} prefix * @private */ Unit.prototype._bestPrefix = function () { // find the best prefix value (resulting in the value of which // the absolute value of the log10 is closest to zero, // though with a little offset of 1.2 for nicer values: you get a // sequence 1mm 100mm 500mm 0.6m 1m 10m 100m 500m 0.6km 1km ... var absValue = Math.abs(this.value / this.unit.value); var bestPrefix = PREFIX_NONE; var bestDiff = Math.abs( Math.log(absValue / bestPrefix.value) / Math.LN10 - 1.2); var prefixes = this.unit.prefixes; for (var p in prefixes) { if (prefixes.hasOwnProperty(p)) { var prefix = prefixes[p]; if (prefix.scientific) { var diff = Math.abs( Math.log(absValue / prefix.value) / Math.LN10 - 1.2); if (diff < bestDiff) { bestPrefix = prefix; bestDiff = diff; } } } } return bestPrefix; }; var PREFIXES = { NONE: { '': {name: '', value: 1, scientific: true} }, SHORT: { '': {name: '', value: 1, scientific: true}, 'da': {name: 'da', value: 1e1, scientific: false}, 'h': {name: 'h', value: 1e2, scientific: false}, 'k': {name: 'k', value: 1e3, scientific: true}, 'M': {name: 'M', value: 1e6, scientific: true}, 'G': {name: 'G', value: 1e9, scientific: true}, 'T': {name: 'T', value: 1e12, scientific: true}, 'P': {name: 'P', value: 1e15, scientific: true}, 'E': {name: 'E', value: 1e18, scientific: true}, 'Z': {name: 'Z', value: 1e21, scientific: true}, 'Y': {name: 'Y', value: 1e24, scientific: true}, 'd': {name: 'd', value: 1e-1, scientific: false}, 'c': {name: 'c', value: 1e-2, scientific: false}, 'm': {name: 'm', value: 1e-3, scientific: true}, 'u': {name: 'u', value: 1e-6, scientific: true}, 'n': {name: 'n', value: 1e-9, scientific: true}, 'p': {name: 'p', value: 1e-12, scientific: true}, 'f': {name: 'f', value: 1e-15, scientific: true}, 'a': {name: 'a', value: 1e-18, scientific: true}, 'z': {name: 'z', value: 1e-21, scientific: true}, 'y': {name: 'y', value: 1e-24, scientific: true} }, LONG: { '': {name: '', value: 1, scientific: true}, 'deca': {name: 'deca', value: 1e1, scientific: false}, 'hecto': {name: 'hecto', value: 1e2, scientific: false}, 'kilo': {name: 'kilo', value: 1e3, scientific: true}, 'mega': {name: 'mega', value: 1e6, scientific: true}, 'giga': {name: 'giga', value: 1e9, scientific: true}, 'tera': {name: 'tera', value: 1e12, scientific: true}, 'peta': {name: 'peta', value: 1e15, scientific: true}, 'exa': {name: 'exa', value: 1e18, scientific: true}, 'zetta': {name: 'zetta', value: 1e21, scientific: true}, 'yotta': {name: 'yotta', value: 1e24, scientific: true}, 'deci': {name: 'deci', value: 1e-1, scientific: false}, 'centi': {name: 'centi', value: 1e-2, scientific: false}, 'milli': {name: 'milli', value: 1e-3, scientific: true}, 'micro': {name: 'micro', value: 1e-6, scientific: true}, 'nano': {name: 'nano', value: 1e-9, scientific: true}, 'pico': {name: 'pico', value: 1e-12, scientific: true}, 'femto': {name: 'femto', value: 1e-15, scientific: true}, 'atto': {name: 'atto', value: 1e-18, scientific: true}, 'zepto': {name: 'zepto', value: 1e-21, scientific: true}, 'yocto': {name: 'yocto', value: 1e-24, scientific: true} }, SQUARED: { '': {name: '', value: 1, scientific: true}, 'da': {name: 'da', value: 1e2, scientific: false}, 'h': {name: 'h', value: 1e4, scientific: false}, 'k': {name: 'k', value: 1e6, scientific: true}, 'M': {name: 'M', value: 1e12, scientific: true}, 'G': {name: 'G', value: 1e18, scientific: true}, 'T': {name: 'T', value: 1e24, scientific: true}, 'P': {name: 'P', value: 1e30, scientific: true}, 'E': {name: 'E', value: 1e36, scientific: true}, 'Z': {name: 'Z', value: 1e42, scientific: true}, 'Y': {name: 'Y', value: 1e48, scientific: true}, 'd': {name: 'd', value: 1e-2, scientific: false}, 'c': {name: 'c', value: 1e-4, scientific: false}, 'm': {name: 'm', value: 1e-6, scientific: true}, 'u': {name: 'u', value: 1e-12, scientific: true}, 'n': {name: 'n', value: 1e-18, scientific: true}, 'p': {name: 'p', value: 1e-24, scientific: true}, 'f': {name: 'f', value: 1e-30, scientific: true}, 'a': {name: 'a', value: 1e-36, scientific: true}, 'z': {name: 'z', value: 1e-42, scientific: true}, 'y': {name: 'y', value: 1e-42, scientific: true} }, CUBIC: { '': {name: '', value: 1, scientific: true}, 'da': {name: 'da', value: 1e3, scientific: false}, 'h': {name: 'h', value: 1e6, scientific: false}, 'k': {name: 'k', value: 1e9, scientific: true}, 'M': {name: 'M', value: 1e18, scientific: true}, 'G': {name: 'G', value: 1e27, scientific: true}, 'T': {name: 'T', value: 1e36, scientific: true}, 'P': {name: 'P', value: 1e45, scientific: true}, 'E': {name: 'E', value: 1e54, scientific: true}, 'Z': {name: 'Z', value: 1e63, scientific: true}, 'Y': {name: 'Y', value: 1e72, scientific: true}, 'd': {name: 'd', value: 1e-3, scientific: false}, 'c': {name: 'c', value: 1e-6, scientific: false}, 'm': {name: 'm', value: 1e-9, scientific: true}, 'u': {name: 'u', value: 1e-18, scientific: true}, 'n': {name: 'n', value: 1e-27, scientific: true}, 'p': {name: 'p', value: 1e-36, scientific: true}, 'f': {name: 'f', value: 1e-45, scientific: true}, 'a': {name: 'a', value: 1e-54, scientific: true}, 'z': {name: 'z', value: 1e-63, scientific: true}, 'y': {name: 'y', value: 1e-72, scientific: true} }, BINARY_SHORT: { '': {name: '', value: 1, scientific: true}, 'k': {name: 'k', value: 1024, scientific: true}, 'M': {name: 'M', value: Math.pow(1024, 2), scientific: true}, 'G': {name: 'G', value: Math.pow(1024, 3), scientific: true}, 'T': {name: 'T', value: Math.pow(1024, 4), scientific: true}, 'P': {name: 'P', value: Math.pow(1024, 5), scientific: true}, 'E': {name: 'E', value: Math.pow(1024, 6), scientific: true}, 'Z': {name: 'Z', value: Math.pow(1024, 7), scientific: true}, 'Y': {name: 'Y', value: Math.pow(1024, 8), scientific: true}, 'Ki': {name: 'Ki', value: 1024, scientific: true}, 'Mi': {name: 'Mi', value: Math.pow(1024, 2), scientific: true}, 'Gi': {name: 'Gi', value: Math.pow(1024, 3), scientific: true}, 'Ti': {name: 'Ti', value: Math.pow(1024, 4), scientific: true}, 'Pi': {name: 'Pi', value: Math.pow(1024, 5), scientific: true}, 'Ei': {name: 'Ei', value: Math.pow(1024, 6), scientific: true}, 'Zi': {name: 'Zi', value: Math.pow(1024, 7), scientific: true}, 'Yi': {name: 'Yi', value: Math.pow(1024, 8), scientific: true} }, BINARY_LONG: { '': {name: '', value: 1, scientific: true}, 'kilo': {name: 'kilo', value: 1024, scientific: true}, 'mega': {name: 'mega', value: Math.pow(1024, 2), scientific: true}, 'giga': {name: 'giga', value: Math.pow(1024, 3), scientific: true}, 'tera': {name: 'tera', value: Math.pow(1024, 4), scientific: true}, 'peta': {name: 'peta', value: Math.pow(1024, 5), scientific: true}, 'exa': {name: 'exa', value: Math.pow(1024, 6), scientific: true}, 'zetta': {name: 'zetta', value: Math.pow(1024, 7), scientific: true}, 'yotta': {name: 'yotta', value: Math.pow(1024, 8), scientific: true}, 'kibi': {name: 'kibi', value: 1024, scientific: true}, 'mebi': {name: 'mebi', value: Math.pow(1024, 2), scientific: true}, 'gibi': {name: 'gibi', value: Math.pow(1024, 3), scientific: true}, 'tebi': {name: 'tebi', value: Math.pow(1024, 4), scientific: true}, 'pebi': {name: 'pebi', value: Math.pow(1024, 5), scientific: true}, 'exi': {name: 'exi', value: Math.pow(1024, 6), scientific: true}, 'zebi': {name: 'zebi', value: Math.pow(1024, 7), scientific: true}, 'yobi': {name: 'yobi', value: Math.pow(1024, 8), scientific: true} } }; var PREFIX_NONE = {name: '', value: 1, scientific: true}; var BASE_UNITS = { NONE: {}, LENGTH: {}, // meter MASS: {}, // kilogram TIME: {}, // second CURRENT: {}, // ampere TEMPERATURE: {}, // kelvin LUMINOUS_INTENSITY: {}, // candela AMOUNT_OF_SUBSTANCE: {}, // mole FORCE: {}, // Newton SURFACE: {}, // m2 VOLUME: {}, // m3 ANGLE: {}, // rad BIT: {} // bit (digital) }; BASE_UNIT_NONE = {}; UNIT_NONE = {name: '', base: BASE_UNIT_NONE, value: 1, offset: 0}; var UNITS = { // length meter: {name: 'meter', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.LONG, value: 1, offset: 0}, inch: {name: 'inch', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.0254, offset: 0}, foot: {name: 'foot', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.3048, offset: 0}, yard: {name: 'yard', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.9144, offset: 0}, mile: {name: 'mile', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 1609.344, offset: 0}, link: {name: 'link', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.201168, offset: 0}, rod: {name: 'rod', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 5.029210, offset: 0}, chain: {name: 'chain', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 20.1168, offset: 0}, angstrom: {name: 'angstrom', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 1e-10, offset: 0}, m: {name: 'm', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.SHORT, value: 1, offset: 0}, 'in': {name: 'in', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.0254, offset: 0}, ft: {name: 'ft', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.3048, offset: 0}, yd: {name: 'yd', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.9144, offset: 0}, mi: {name: 'mi', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 1609.344, offset: 0}, li: {name: 'li', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.201168, offset: 0}, rd: {name: 'rd', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 5.029210, offset: 0}, ch: {name: 'ch', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 20.1168, offset: 0}, mil: {name: 'mil', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.0000254, offset: 0}, // 1/1000 inch // Surface m2: {name: 'm2', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.SQUARED, value: 1, offset: 0}, sqin: {name: 'sqin', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 0.00064516, offset: 0}, // 645.16 mm2 sqft: {name: 'sqft', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 0.09290304, offset: 0}, // 0.09290304 m2 sqyd: {name: 'sqyd', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 0.83612736, offset: 0}, // 0.83612736 m2 sqmi: {name: 'sqmi', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 2589988.110336, offset: 0}, // 2.589988110336 km2 sqrd: {name: 'sqrd', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 25.29295, offset: 0}, // 25.29295 m2 sqch: {name: 'sqch', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 404.6873, offset: 0}, // 404.6873 m2 sqmil: {name: 'sqmil', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 6.4516e-10, offset: 0}, // 6.4516 * 10^-10 m2 // Volume m3: {name: 'm3', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.CUBIC, value: 1, offset: 0}, L: {name: 'L', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.SHORT, value: 0.001, offset: 0}, // litre l: {name: 'l', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.SHORT, value: 0.001, offset: 0}, // litre litre: {name: 'litre', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.LONG, value: 0.001, offset: 0}, cuin: {name: 'cuin', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 1.6387064e-5, offset: 0}, // 1.6387064e-5 m3 cuft: {name: 'cuft', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.028316846592, offset: 0}, // 28.316 846 592 L cuyd: {name: 'cuyd', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.764554857984, offset: 0}, // 764.554 857 984 L teaspoon: {name: 'teaspoon', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.000005, offset: 0}, // 5 mL tablespoon: {name: 'tablespoon', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.000015, offset: 0}, // 15 mL //{name: 'cup', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.000240, offset: 0}, // 240 mL // not possible, we have already another cup // Liquid volume minim: {name: 'minim', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00000006161152, offset: 0}, // 0.06161152 mL fluiddram: {name: 'fluiddram', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0000036966911, offset: 0}, // 3.696691 mL fluidounce: {name: 'fluidounce', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00002957353, offset: 0}, // 29.57353 mL gill: {name: 'gill', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0001182941, offset: 0}, // 118.2941 mL cc: {name: 'cc', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 1e-6, offset: 0}, // 1e-6 L cup: {name: 'cup', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0002365882, offset: 0}, // 236.5882 mL pint: {name: 'pint', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0004731765, offset: 0}, // 473.1765 mL quart: {name: 'quart', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0009463529, offset: 0}, // 946.3529 mL gallon: {name: 'gallon', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.003785412, offset: 0}, // 3.785412 L beerbarrel: {name: 'beerbarrel', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1173478, offset: 0}, // 117.3478 L oilbarrel: {name: 'oilbarrel', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1589873, offset: 0}, // 158.9873 L hogshead: {name: 'hogshead', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.2384810, offset: 0}, // 238.4810 L //{name: 'min', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00000006161152, offset: 0}, // 0.06161152 mL // min is already in use as minute fldr: {name: 'fldr', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0000036966911, offset: 0}, // 3.696691 mL floz: {name: 'floz', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00002957353, offset: 0}, // 29.57353 mL gi: {name: 'gi', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0001182941, offset: 0}, // 118.2941 mL cp: {name: 'cp', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0002365882, offset: 0}, // 236.5882 mL pt: {name: 'pt', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0004731765, offset: 0}, // 473.1765 mL qt: {name: 'qt', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0009463529, offset: 0}, // 946.3529 mL gal: {name: 'gal', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.003785412, offset: 0}, // 3.785412 L bbl: {name: 'bbl', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1173478, offset: 0}, // 117.3478 L obl: {name: 'obl', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1589873, offset: 0}, // 158.9873 L //{name: 'hogshead', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.2384810, offset: 0}, // 238.4810 L // TODO: hh? // Mass g: {name: 'g', base: BASE_UNITS.MASS, prefixes: PREFIXES.SHORT, value: 0.001, offset: 0}, gram: {name: 'gram', base: BASE_UNITS.MASS, prefixes: PREFIXES.LONG, value: 0.001, offset: 0}, ton: {name: 'ton', base: BASE_UNITS.MASS, prefixes: PREFIXES.SHORT, value: 907.18474, offset: 0}, tonne: {name: 'tonne', base: BASE_UNITS.MASS, prefixes: PREFIXES.SHORT, value: 1000, offset: 0}, grain: {name: 'grain', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 64.79891e-6, offset: 0}, dram: {name: 'dram', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 1.7718451953125e-3, offset: 0}, ounce: {name: 'ounce', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 28.349523125e-3, offset: 0}, poundmass: {name: 'poundmass', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 453.59237e-3, offset: 0}, hundredweight: {name: 'hundredweight', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 45.359237, offset: 0}, stick: {name: 'stick', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 115e-3, offset: 0}, gr: {name: 'gr', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 64.79891e-6, offset: 0}, dr: {name: 'dr', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 1.7718451953125e-3, offset: 0}, oz: {name: 'oz', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 28.349523125e-3, offset: 0}, lbm: {name: 'lbm', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 453.59237e-3, offset: 0}, cwt: {name: 'cwt', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 45.359237, offset: 0}, // Time s: {name: 's', base: BASE_UNITS.TIME, prefixes: PREFIXES.SHORT, value: 1, offset: 0}, min: {name: 'min', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 60, offset: 0}, h: {name: 'h', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 3600, offset: 0}, second: {name: 'second', base: BASE_UNITS.TIME, prefixes: PREFIXES.LONG, value: 1, offset: 0}, sec: {name: 'sec', base: BASE_UNITS.TIME, prefixes: PREFIXES.LONG, value: 1, offset: 0}, minute: {name: 'minute', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 60, offset: 0}, hour: {name: 'hour', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 3600, offset: 0}, day: {name: 'day', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 86400, offset: 0}, // Angle rad: {name: 'rad', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 1, offset: 0}, // deg = rad / (2*pi) * 360 = rad / 0.017453292519943295769236907684888 deg: {name: 'deg', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 0.017453292519943295769236907684888, offset: 0}, // grad = rad / (2*pi) * 400 = rad / 0.015707963267948966192313216916399 grad: {name: 'grad', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 0.015707963267948966192313216916399, offset: 0}, // cycle = rad / (2*pi) = rad / 6.2831853071795864769252867665793 cycle: {name: 'cycle', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 6.2831853071795864769252867665793, offset: 0}, // Electric current A: {name: 'A', base: BASE_UNITS.CURRENT, prefixes: PREFIXES.SHORT, value: 1, offset: 0}, ampere: {name: 'ampere', base: BASE_UNITS.CURRENT, prefixes: PREFIXES.LONG, value: 1, offset: 0}, // Temperature // K(C) = °C + 273.15 // K(F) = (°F + 459.67) / 1.8 // K(R) = °R / 1.8 K: {name: 'K', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 0}, degC: {name: 'degC', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 273.15}, degF: {name: 'degF', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 459.67}, degR: {name: 'degR', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 0}, kelvin: {name: 'kelvin', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 0}, celsius: {name: 'celsius', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 273.15}, fahrenheit: {name: 'fahrenheit', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 459.67}, rankine: {name: 'rankine', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 0}, // amount of substance mol: {name: 'mol', base: BASE_UNITS.AMOUNT_OF_SUBSTANCE, prefixes: PREFIXES.NONE, value: 1, offset: 0}, mole: {name: 'mole', base: BASE_UNITS.AMOUNT_OF_SUBSTANCE, prefixes: PREFIXES.NONE, value: 1, offset: 0}, // luminous intensity cd: {name: 'cd', base: BASE_UNITS.LUMINOUS_INTENSITY, prefixes: PREFIXES.NONE, value: 1, offset: 0}, candela: {name: 'candela', base: BASE_UNITS.LUMINOUS_INTENSITY, prefixes: PREFIXES.NONE, value: 1, offset: 0}, // TODO: units STERADIAN //{name: 'sr', base: BASE_UNITS.STERADIAN, prefixes: PREFIXES.NONE, value: 1, offset: 0}, //{name: 'steradian', base: BASE_UNITS.STERADIAN, prefixes: PREFIXES.NONE, value: 1, offset: 0}, // Force N: {name: 'N', base: BASE_UNITS.FORCE, prefixes: PREFIXES.SHORT, value: 1, offset: 0}, newton: {name: 'newton', base: BASE_UNITS.FORCE, prefixes: PREFIXES.LONG, value: 1, offset: 0}, lbf: {name: 'lbf', base: BASE_UNITS.FORCE, prefixes: PREFIXES.NONE, value: 4.4482216152605, offset: 0}, poundforce: {name: 'poundforce', base: BASE_UNITS.FORCE, prefixes: PREFIXES.NONE, value: 4.4482216152605, offset: 0}, // Binary b: {name: 'b', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_SHORT, value: 1, offset: 0}, bits: {name: 'bits', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_LONG, value: 1, offset: 0}, B: {name: 'B', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_SHORT, value: 8, offset: 0}, bytes: {name: 'bytes', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_LONG, value: 8, offset: 0} }; // plurals var PLURALS = { meters: 'meter', inches: 'inch', feet: 'foot', yards: 'yard', miles: 'mile', links: 'link', rods: 'rod', chains: 'chain', angstroms: 'angstrom', litres: 'litre', teaspoons: 'teaspoon', tablespoons: 'tablespoon', minims: 'minim', fluiddrams: 'fluiddram', fluidounces: 'fluidounce', gills: 'gill', cups: 'cup', pints: 'pint', quarts: 'quart', gallons: 'gallon', beerbarrels: 'beerbarrel', oilbarrels: 'oilbarrel', hogsheads: 'hogshead', grams: 'gram', tons: 'ton', tonnes: 'tonne', grains: 'grain', drams: 'dram', ounces: 'ounce', poundmasses: 'poundmass', hundredweights: 'hundredweight', sticks: 'stick', seconds: 'second', minutes: 'minute', hours: 'hour', days: 'day', radians: 'rad', degrees: 'deg', gradients: 'grad', cycles: 'cycle', amperes: 'ampere', moles: 'mole' }; for (var name in PLURALS) { /* istanbul ignore next (we cannot really test next statement) */ if (PLURALS.hasOwnProperty(name)) { var unit = UNITS[PLURALS[name]]; var plural = Object.create(unit); plural.name = name; UNITS[name] = plural; } } // aliases UNITS.lt = UNITS.l; UNITS.liter = UNITS.litre; UNITS.liters = UNITS.litres; UNITS.lb = UNITS.lbm; UNITS.lbs = UNITS.lbm; Unit.PREFIXES = PREFIXES; Unit.BASE_UNITS = BASE_UNITS; Unit.UNITS = UNITS; // end of unit aliases // exports module.exports = Unit;