Skip to content

Latest commit

 

History

History
670 lines (571 loc) · 35.4 KB

README.md

File metadata and controls

670 lines (571 loc) · 35.4 KB

MultiConvert Data

This repository contains source data for the MultiConvert app.

Building and Testing

To build and test the data files, you need Node.js and UglifyJS (npm install uglify-js -g). The build script build.sh will load and validate all data files, run all tests, and if no errors are encountered, produce minified data files.

$ ./build.sh
Compiling...
194 unit types defined
16 functions defined
1194 units defined
2659 units defined or included
3 includes defined
119 elements defined
11 solvers or calculators defined
0 errors in data
0 warnings in data
865 tests executed
865 tests passed
0 tests failed
0 errors total
0 warnings total
Wrote mcdbmain.js
Wrote mcdbmisc.js
Minifying...
-rw-rw-r-- 1 user group 189969 May  1 18:52 mcdbmain.js
-rw-rw-r-- 1 user group 165284 May  1 18:52 mcdbmain.min.js
-rw-rw-r-- 1 user group  30999 May  1 18:52 mcdbmisc.js
-rw-rw-r-- 1 user group  26071 May  1 18:52 mcdbmisc.min.js
$

The minified data files are currently mostly useless to most people. If you are using this data in your own application, it is recommended to use the JSON source files for your own purposes and use the build script just for validation and testing.

Unit Identifiers

Units in the MultiConvert database are identified by a lowercase letter followed by one or more digits. The following ranges are currently used:

range file usage
u0u49 base-si.json Base units and coherent derived units in the International System of Units (SI).
u50u99 base-nonsi.json Base units and coherent derived units not recognized by SI.
u100u199 derived-si.json Non-SI units accepted for use with SI.
u200u299 derived-length.json Non-SI units of length.
u300u399 derived-area.json Non-SI units of area.
u400u499 derived-volume.json Non-SI units of volume.
u500u599 derived-vel-acc.json Non-SI units of velocity and acceleration.
u600u699 derived-mass.json Non-SI units of mass.
u700u799 derived-force.json Non-SI units of force.
u800u899 derived-time.json Non-SI units of time.
u900u999 derived‑temperature.json Non-SI units of temperature.
u1000u1099 derived-angle.json Non-SI units of angular displacement.
u1100u1199 derived-power.json Non-SI units of power.
u1200u1299 derived-pressure.json Non-SI units of pressure.
u1300u1399 derived-frequency.json Non-SI units of frequency.
u1400u1499 derived-voltage.json Non-SI units of voltage.
u1500u1599 derived-current.json Non-SI units of current.
u1600u1699 derived-data.json Units of data or information (bits and bytes).
u1700u1799 derived-sheets.json Units of page or sheet count (quires, reams, and bales).
u1800u1899 derived-hardness.json Units of hardness of materials.
u1900u1999 derived-misc.json Units expressed with a single decimal number not included in other categories.
u2000u2099 dimensionless.json Dimensionless units.
n100n199 viscosity.json Units of kinematic viscosity.
n200n299 shoe-size.json Shoe sizes.
n1000n1001 clock-time.json Biel Mean Time (also known as Swatch Internet Time).
z0z2 frequency-color.json
frequency-pitch.json
guaca.json
Units not expressed with a single decimal number not included in other categories.
z100z169 numeral-system.json Numeral systems using ASCII characters (binary, octal, hexadecimal, et cetera).
z170z199 numeral-system.json Non-positional or non-decimal numeral systems (Roman, Kaktovik, et cetera).
z200z299 coordinate-system.json Coordinate systems (Cartesian, polar, spherical, et cetera).
z300z399 color-space.json Color spaces (RGB, HSV, YIQ, YUV, et cetera).
z800z899 numeral-system.json Numeral systems using non-ASCII digits (Arabic-Indic, Devanagari, et cetera).
z900-z999 numeral-system.json Numeral systems using an informal encoding in the Unicode Private Use Area (Tengwar, Klingon, et cetera).
z1000z1999 clock-time.json Wall clock time in different time zones.
k0k5 capacitor-code.json
inductor-code.json
resistor-code.json
Color codes and EIA codes for electronic components.
c0c19999 Units of currency. These are not present in this repository but generated dynamically by MultiConvert from third-party data.
d0d99 dependent.json Units for which conversion requires the specification of an independent variable (such as air temperature for Mach number).
m0m999 medical.json Units of concentration of various medications.
p0p99 planck.json Planck units.

Identifiers starting with e, f, i, s, and t are not used for units as they are used for other objects.

Identifiers starting with n are used for units for which conversion is noninvertible or inexact. Biel Mean Time uses modular arithmetic so is noninvertible. Shoe sizes vary greatly between manufacturers so are impossible to convert exactly. Kinematic viscosity conversions are both inexact and, since they involve a calculation more complex than a simple series of arithmetic operations, produce slightly different results depending on the direction of the conversion, making them noninvertible.

Unit Expressions

Units created through the use of SI or IEEE prefixes or multiplication and division of base units are not defined in data files but derived mathematically, and as such are identified not by a single identifier but by a unit expression. For example:

expression unit
u0_3 kilometers
u0_-3 millimeters
u0^2 square meters
u0/u2 meters per second
u10*u0 newton meters
u700*u0_-2 dyne centimeters
u51.10 kibibits (u51 × 210)
u1602.20 mebibytes (u1602 × 220)
u13/u0^2*u4 watts (u13) per square meter (u0^2) kelvin (u4)
u1103/u210^2*u101*u902 British thermal units (u1103) per square foot (u210^2) hour (u101) degree Rankine (u902)
u1/u0^0.5*u2^2 kilograms (u1) per square root meter (u0^0.5) square second (u2^2)

As shown above, unit expressions can get arbitrarily complex.

Division in unit expressions has lower precedence than multiplication, so u0*u1/u2*u3 is equivalent to (u0*u1)/(u2*u3), not ((u0*u1)/u2)*u3.

Looking Up Unit Identifiers

If you need to look up an identifier, you can use the included mcvt.js utility program. You can look up by identifier, symbol, or name.

$ ./mcvt.js u0

d    id    type    sym    name      dimension
-    --    ----    ---    ------    ---------
     u0    unit    m      meters    length

$ ./mcvt.js meters

d    id    type    sym    name      dimension
-    --    ----    ---    ------    ---------
     u0    unit    m      meters    length

$

If multiple objects match your query, mcvt.js will list all matched objects. An asterisk in the first column indicates the default specified in the file disambiguation.json.

$ ./mcvt.js m

d    id       type    sym    name                   dimension
-    -----    ----    ---    -------------------    ------------------
*    u0       unit    m      meters                 length
     u1300    unit    m      meters (wavelength)    frequency (time⁻¹)

$

You can look up unit expressions as well.

$ ./mcvt.js u1/u0^0.5*u2^2

d    id                type    sym           name                                             dimension
-    --------------    ----    ----------    ---------------------------------------------    -----------------------------------------
     u1/u0^0.5*u2^2    unit    kg/m⁰⸳⁵·s²    kilograms per square root meter square second    fracture toughness (mass/length⁰⸳⁵·time²)

$

Performing Unit Conversions and Calculations

The mcvt.js utility program can also perform unit conversions and calculations. All the usual mathematical operators and functions are available, as well as some unusual ones.

$ ./mcvt.js '1 mile to kilometers'
1.609344 kilometers
$ ./mcvt.js '2 + 2'
4
$ ./mcvt.js '2 miles + 2 kilometers'
3.242742384474668 miles
$ ./mcvt.js '2 kilometers + 2 miles'
5.218688 kilometers
$ ./mcvt.js 'sqrt(16 `square meters`)'
4 meters
$ ./mcvt.js 'rsr(2 ohms, 6 ohms)'
1.5 ohms
$

You can also run mcvt.js without arguments to start an interactive shell.

$ ./mcvt.js
mcvt> 1 mile to kilometers
1.609344 kilometers
mcvt> 2 + 2
4
mcvt> 2 miles + 2 kilometers
3.242742384474668 miles
mcvt> 2 kilometers + 2 miles
5.218688 kilometers
mcvt> sqrt(16 `square meters`)
4 meters
mcvt> rsr(2 ohms, 6 ohms)
1.5 ohms
mcvt> quit
$

Assignment is also supported using the := operator and works with all kinds of objects, not just numbers.

$ ./mcvt.js
mcvt> v1 := 3.218688 kilometers
3.218688 kilometers
mcvt> v1 to miles
2 miles
mcvt> x := 2
2
mcvt> f := miles to kilometers
function `miles to kilometers`
mcvt> f(x)
3.218688
mcvt> quit
$

Example Unit Definitions

Base Units

Consider the definition of the meter:

"u0": {
	"symbol": "m",
	"name": {
		"en": {
			"1": "meter",
			"*": "meters"
		}
	},
	"dimension": {
		"length": 1
	}
}

This is read as "u0, the meter, is the base unit for length."

Derived Units Using Multiplication & Division

Consider the definition of the minute:

"u100": {
	"symbol": "min",
	"name": {
		"en": {
			"1": "minute",
			"*": "minutes"
		}
	},
	"multiplier": 60,
	"dimension": {
		"time": 1
	}
}

This is read as "u100, the minute, is 60 seconds (the base unit for time)."

Consider the definition of the liter:

"u107": {
	"symbol": "L",
	"name": {
		"en": {
			"1": "liter",
			"*": "liters"
		}
	},
	"divisor": 1000,
	"dimension": {
		"length": 3
	}
}

This is read as "u107, the liter, is one 1000th of a cubic meter (the base unit for length cubed, aka volume)."

Consider the definition of the knot:

"u163": {
	"symbol": "kn",
	"name": {
		"en": {
			"1": "knot",
			"*": "knots"
		}
	},
	"multiplier": 1852,
	"divisor": 3600,
	"dimension": {
		"length": 1,
		"time": -1
	}
}

This is read as "u163, the knot, is 1852/3600 meters per second (the base unit for length over time, aka velocity)."

Derived Units Using Reversible Operations

Consider the definition of degrees Fahrenheit:

"u900": {
	"symbol": "°F",
	"name": {
		"en": {
			"1": "degree Fahrenheit",
			"*": "degrees Fahrenheit"
		}
	},
	"instructions": "S32 M5 D9 A273.15",
	"dimension": {
		"temperature": 1
	}
}

This is read as "to convert from u900, degrees Fahrenheit, to kelvin (the base unit for temperature), subtract 32, multiply by 5, divide by 9, and add 273.15." (To convert in the other direction, the instructions must of course be performed in reverse.)

The following instructions are allowed in the instructions field:

instruction operation formula reverse operation
Aa add x' = x + a Sa
Sa subtract x' = xa Aa
Za subtract from x' = ax Za
Ma multiply x' = x × a Da
Da divide x' = x ÷ a Ma
Ga divide into x' = a ÷ x Ga
Pa power x' = xa Ra
Ra root x' = xa Pa
Xa exponential x' = ax La
La logarithm x' = loga x Xa
Ea natural exp x' = exa Na
Na natural log x' = ln (x + a) Ea
Ca circumference x' = x × π ÷ a Qa
Qa diameter x' = x × a ÷ π Ca
R2 sqrt x' = √x P2
R3 cbrt x' = ∛x P3
L2 log2 x' = log2 x X2
L10 log10 x' = log10 x X10
E0 exp x' = ex N0
E1 expm1 x' = ex − 1 N1
N0 log x' = ln x E0
N1 log1p x' = ln (x + 1) E1
C180 toRadians x' = x × π ÷ 180 Q180
Q180 toDegrees x' = x × 180 ÷ π C180
F1 sin x' = sin x V1
F2 cos x' = cos x V2
F3 tan x' = tan x V3
F4 cot x' = cot x V4
F5 sec x' = sec x V5
F6 csc x' = csc x V6
F7 sinh x' = sinh x V7
F8 cosh x' = cosh x V8
F9 tanh x' = tanh x V9
F10 coth x' = coth x V10
F11 sech x' = sech x V11
F12 csch x' = csch x V12
V1 asin x' = sin−1 x F1
V2 acos x' = cos−1 x F2
V3 atan x' = tan−1 x F3
V4 acot x' = cot−1 x F4
V5 asec x' = sec−1 x F5
V6 acsc x' = csc−1 x F6
V7 asinh x' = sinh−1 x F7
V8 acosh x' = cosh−1 x F8
V9 atanh x' = tanh−1 x F9
V10 acoth x' = coth−1 x F10
V11 asech x' = sech−1 x F11
V12 acsch x' = csch−1 x F12

Instructions such as integer divide, modulus, comparisons, gamma function, etc. are not available because they cannot be performed in reverse.

Scientific notation uses the underscore (_ instead of E or e) in the instructions field. An instruction such as M2E3 will be interpreted as x' = e2x−3, not x' = 2000x. To get the latter, use the instruction M2_3.

Derived Units Using JavaScript Functions

Consider the definition of the DIN #4 kinematic viscosity cup:

"n144": {
	"symbol": "s",
	"name": {
		"en": {
			"1": "second (DIN #4)",
			"*": "seconds (DIN #4)"
		}
	},
	"parser": "function (a) { return (a * 4.57 - 452 / a) / 100 }",
	"formatter": "function (a) { a *= 100; return (Math.sqrt(a * a + 8263) + a) / 9.14 }",
	"dimension": {
		"length": 2,
		"time": -1
	}
}

This is read as "to convert $a$ from n144, seconds using DIN #4, to square meters per second (the base unit for kinematic viscosity), use the expression $\frac{4.57a-\frac{452}{a}}{100}$; to convert $a$ in the other direction, multiply $a$ by 100, then use the expression $\frac{a+\sqrt{a^2+8263}}{9.14}$."

The input to the parser function and the output of the formatter function need not be a number. Consider the definition of frequency described as musical pitch:

"z1": {
	"name": {
		"en": "note"
	},
	"datatype": "text",
	"parser": [
		"function (a) {",
		"  if (a.trim) a = a.trim();",
		"  if (!a) return NaN;",
		"  var i = 'CCDDEFFGGAAB'.indexOf(a[0].toUpperCase());",
		"  if (i < 0) return NaN;",
		"  a = a.substring(1);",
		"  if (a.trim) a = a.trim();",
		"  while (a) {",
		"    if (a[0] === '#' || a[0] === '\u266F') i++;",
		"    else if (a[0] === 'b' || a[0] === '\u266D') i--;",
		"    else if (a[0] !== '\u266E') break;"
		"    a = a.substring(1);",
		"  }",
		"  if (a.trim) a = a.trim();",
		"  if (!a.length || !isFinite(a)) a = 4;",
		"  return (27.5 * Math.pow(2, (a * 12 + i - 9) / 12));",
		"}"
	],
	"formatter": [
		"function (a) {",
		"  if (!(a = Math.abs(a)) || !isFinite(a)) return '';",
		"  var i = Math.round(Math.log(a / 27.5) * 12 / Math.log(2) + 9);",
		"  a = Math.floor(i / 12);",
		"  return ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'][i - 12 * a] + a;",
		"}"
	],
	"dimension": {
		"time": -1
	}
}

The "datatype": "text" key-value pair indicates that the parser function takes a string and the formatter function returns a string.

The parser and formatter functions in these examples have been prettified for readability. Most functions in the actual data files are minimized.

It is generally recommended for JavaScript functions in unit definitions to use syntax as archaic as possible for maximum compatibility, hence the use of function (a) { ... } instead of a => { ... }, the check for a.trim, the use of var instead of const or let, the expression Math.log(a / 27.5) * 12 / Math.log(2) instead of Math.log2(a / 27.5) * 12, etc.

Example Test Cases

All Singing, All Dancing, All Inputs, All Outputs

Consider this (abbreviated) test case for length:

{
	"name": "inches",
	"u0_-3": 254000,
	"u0_-2": 25400,
	"u0_-1": 2540,
	"u0": 254,
	"u0_1": 25.4,
	"u0_2": 2.54,
	"u0_3": 0.254,
	"u207_-6": 10000000000,
	"u207": 10000,
	"epsilon": 1E-12
}

This test case states that 254000 millimeters (u0_-3), 25400 centimeters (u0_-2), 2540 decimeters (u0_-1), 254 meters (u0), 25.4 decameters (u0_1), 2.54 hectometers (u0_2), 0.254 kilometers (u0_3), 10000000000 microinches (u207_-6), and 10000 inches (u207) should all convert to each other. The actual number of conversions performed and verified is n2 where n is the number of key-value pairs. Conversions from a unit to itself are also included.

The epsilon key-value pair states that the maximum allowed difference |ab| between the actual result a and expected result b of a conversion shall be the greater of ( |a| + |b| ) · ε and ε (here ε = 10-12). This is often necessary because floating point has issues (if you know, you know). An epsilon of zero means a and b must be exactly equal (in the floating point sense, not the real number sense; if you know, you know); an epsilon of 1 means a and b may be anything as long as they have the same sign. Most test cases use an epsilon of 10-15 or 10-12. Some unlucky test cases may have an epsilon as large as 10-3; it is not recommended to have an epsilon larger than this.

One Half of an Input/Output

Consider this (abbreviated) test case for numeral system:

{
	"name": "one half",
	"z102": "0.1",
	"z104": "0.2",
	"z106": "0.3",
	"z108": "0.4",
	"z110": "0.5",
	"z112": "0.6",
	"z116": "0.8",
	"z120": "0.A",
	"z136": "0.I",
	"z160": "0.U",
	"inputs": {
		"z120": "0.a",
		"z136": "0.i"
	},
	"outputs": {
		"z199": ""
	}
}

In this test case, the values of 0.a for z120 (vigesimal or base 20) and 0.i for z136 (hexatrigesimal or base 36) should only be tested as inputs; they should not be tested as outputs because the lowercase letters of the expected output would not match the uppercase letters of the actual output (0.A and 0.I respectively). Similarly, the empty string for z199 (Roman numerals) should only be tested as an output (given a non-integer, the Roman numeral conversion returns an empty string); it should not be tested as an input because an empty string would result in the actual output of an empty string for every other unit, which will not match any of the expected outputs.

Accounting for Floating Point Error in Strings

Consider this test case for balanced ternary:

{
	"name": "balanced ternary fractional 1",
	"z103": "-1.1",
	"z193": "-.-",
	"replacements": [
		{
			"replace": "[.][0]2{30}.*",
			"with": ".1"
		},
		{
			"replace": "[.][-]0{30}.*",
			"with": ".-"
		}
	]
}

The replacements field applies regular expression substitutions to the outputs of units with "datatype": "text". In this case, it is used to compensate for inaccuracies introduced by floating point rounding by replacing -1.02222222222222222222222222222222211001200121102012 with -1.1 and -.-0000000000000000000000000000000+--0-++0-++---+-++ with -.-. It is intended to be a functional equivalent of the epsilon field.

Unit Types

Unit types or categories are defined in the file unit-types.json and are identified by a lowercase letter t followed by one or more digits. The following ranges are currently used:

range usage
t0t499 Unit types using base units in the International System of Units (SI) with integer exponents.
t500t999 Unit types using base units in the International System of Units (SI) with non-integer exponents.
t1000t1499 Unit types using base units not recognized by SI with integer exponents.

Currently, the only unit type using SI base units with non-integer exponents is fracture toughness (mass per square root length time squared), and there are no unit types using non-SI base units with non-integer exponents.

Example Unit Types

Consider the definition of energy:

"t55": {
	"icon": "energy.png",
	"name": {
		"en": "energy"
	},
	"name-priority": 1,
	"dimension": {
		"length": 2,
		"mass": 1,
		"time": -2
	}
}

The icon field specifies an image file in the typeicons directory.

The name-priority field, if present, indicates that this unit type is preferred above others with the same dimension when looking up a unit type by dimension. In this case, "energy" is the preferred unit type over "heat" (which has the same dimension of length squared times mass over time squared) as it is more generic.

Consider the definition of fracture toughness:

"t500": {
	"icon": "fracturetoughness.png",
	"name": {
		"en": "fracture toughness"
	},
	"dimension": {
		"length": -0.5,
		"mass": 1,
		"time": -2
	}
}

As demonstrated in this case, dimensions can have half-integer exponents.

Other Objects

The MultiConvert database also includes other objects with identifiers similar to those for units and unit types.

prefix usage
a Reserved for future expansion.
b Reserved for future expansion.
c Units of currency.
d Units for which conversion requires the specification of an independent variable.
e Definitions of chemical elements and collections of their properties.
f JavaScript functions used in unit definitions.
g Reserved for future expansion.
h Reserved for future expansion.
i Collections of units grouped by unit type. Internally known as "includes" or "installation defaults."
j Reserved for future expansion.
k Color codes and EIA codes for electronic components.
l Reserved for future expansion.
m Units of concentration of various medications.
n Units for which conversion is noninvertible or inexact.
o Reserved for future expansion.
p Natural units such as Planck units.
q Reserved for future expansion.
r Reserved for future expansion.
s Solvers and calculators: forms with named unit fields that can be completed given partial input.
t Unit types or categories.
u Ordinary units expressed with a single decimal number.
v Reserved for local use.
w Reserved for local use.
x Reserved for local use.
y Reserved for local use.
z Units expressed with a text string or a tuple of decimal numbers.

Units of Currency

Units of currency are identified by a lowercase letter c followed by one or more digits which encode an ISO 4217 alphabetic currency code. For the ISO 4217 code abc, the corresponding unit identifier is c((a-A)·676+(b-A)·26+(c-A)). For example, USD is c((U-A)·676+(S-A)·26+(D-A)) = c(20·676+18·26+3) = c(13520+468+3) = c13991.

The database includes a unit useful for calculating unit identifiers for currency. In the "numeral system" category, enter "customize" mode and add the "base26" unit, or use the mcvt.js utility:

$ ./mcvt.js '"USD" base26 to decimal'
13991 decimal
$ ./mcvt.js '13991 decimal to base26'
USD base26
$

Chemical Element Data

Chemical elements are identified by a lowercase letter e followed by their atomic number. Properties of chemical elements can be looked up in the "periodic table" category in the "extras" or "tools" mode or using the mcvt.js utility:

$ ./mcvt.js e2

d    id    type       sym    name      dimension
-    --    -------    ---    ------    ---------
     e2    element    He     Helium

$ ./mcvt.js 'e2 `boiling point`'
-268.93 degrees Celsius
$

Chemical element data is stored in the file elements.json. For example:

"2": {
	"symbol": "He",
	"name": {
		"en": "Helium"
	},
	"properties": {
		"t94": {
			"value": 4.0026022,
			"unit": "u141"
		},
		"t153": {
			"value": -273.128,
			"unit": "u110"
		},
		"t154": {
			"value": -268.93,
			"unit": "u110"
		}
	}
}

Keys in elements.json do not begin with the e prefix as it is implied.

Useful identifiers for chemical element data include:

identifier name
t55 energy
t94 mass
t96 molar conductivity
t97 molar energy
t98 molar entropy
t99 molar heat capacity
t100 molar mass
t101 molar volume
t129 substance
t153 melting point
t154 boiling point
t155 electron affinity
t1036 electronegativity
u1 kilograms
u4 kelvin
u5 moles
u12 joules
u50 unos (dimensionless unit)
u108 grams
u110 degrees Celsius
u140 electronvolts
u141 atomic mass units
u143 unified atomic mass units
u144 daltons
u2000 units (dimensionless unit)

JavaScript Functions

Derived units using JavaScript functions can reference other functions defined within the same JSON file. The build script requires these functions to be identified by a lowercase letter f followed by one or more digits. For example, numeral-system.json begins with several functions referenced by multiple "numeral system" units:

"functions": {
	"f0": "function(a){return(a==null)?'':(''+a).replace(/^\\s+|\\s+$/g,'')}",
	"f100": [
		"function(a,b,c,d,s){if(!a)return NaN;",
		"if(a=='\u221E'||a=='+\u221E')return+1/0;if(a=='-\u221E')return-1/0;",
		...
	],
	"f101": [
		"function(a,b,c,d,s){",
		"if(!isFinite(a))return(a<0)?'-\u221E':(a>0)?'\u221E':'';",
		...
	],
	...
}

Includes & Installation Defaults

These objects consist of a list of categories, with a list of units under each category. They can also reference another such object to include that object's categories and units. They are interchangeably called "includes" or "installation defaults." They are identified by a lowercase letter i followed by one or more digits. The total number of these objects is very small and there is currently no reason to define your own.

identifier purpose
i0 Used internally by MultiConvert 5 to refer to the user's current set of units.
i1 The set of units loaded by default when selecting "ALL the Things!" or "I Want It All" upon first launch.
i2 The set of units loaded by default when selecting "Back to Basics" or "Keep It Simple" upon first launch.
i36 The "currency" category and the set of all supported currencies. Generated from third-party data and included by i1.
i68 A set of units automatically loaded and indexed so they can be listed when adding a unit in "customize" mode.
i162 The "currency" category and a set of commonly-traded currencies. Generated from third-party data and included by i2.

Solvers & Calculators

A solver or calculator is a set of named unit fields for which all values can be calculated given a partial set of input values. For example, given any two of voltage, current, resistance, and power, the other two can be calculated; or given three angles or side lengths of a triangle, the other three angles or side lengths can be calculated (with some caveats). Each unit field is declared as either "independent" (its value must be given, and cannot be calculated from other values) or "dependent" (its value can be calculated from other values) and assigned a register number. Each possible set of given dependent values, identified by the corresponding register numbers, is associated with a JavaScript function which calculates the other dependent values. MultiConvert keeps track of the order in which values are entered into unit fields and uses this order to evaluate the appropriate function.