DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 5.15 Converting Between Units of Measurement

5.15.1 Problem

You want to convert between Fahrenheit and Centigrade, pounds and kilograms, or other units of measurement.

5.15.2 Solution

Write a custom method to perform the conversion and add it to the Math class.

5.15.3 Discussion

There are various systems of measurement used throughout the world. For example, temperature is commonly measured with both the Fahrenheit and Centigrade scales, and weight is commonly measured using both pounds and kilograms. For these reasons, you may need to convert from one unit of measurement to another.

Each of these conversions has its own algorithm. For example, to convert from Centigrade to Fahrenheit, you should multiply by 9/5 and then add 32 (to convert from Fahrenheit to Centigrade, subtract 32 and multiply by 5/9). Likewise, you can multiply by 2.2 to convert pounds to kilograms, and you can divide by 2.2 to convert kilograms to pounds. We also saw in Recipe 5.12 how to convert angles from degrees to radians and vice versa.

Here is a temperature converter. The method takes three parameters: the name of the units from which you are converting, the name of the units to which you are converting, and the value to convert. In this example code, we define conversions between Fahrenheit and Centigrade ("F" is interpreted to mean "Fahrenheit"; "C" and "Celsius" are recognized alternatives to "Centigrade"):

Math.convertTemperature = function (fMeasure, tMeasure, val) {
  // Convert all names to lowercase to match any capitalization.
  fMeasure = fMeasure.toLowerCase(  );
  tMeasure = tMeasure.toLowerCase(  );
  
  if ( (fMeasure == "centigrade" || fMeasure == "celsius" || fMeasure == "c")
       && (tMeasure == "fahrenheit" || tMeasure == "f") ) {
    // Convert Centigrade to Fahrenheit.
    return (val * 9/5) + 32;
  } else if ( (fMeasure == "fahrenheit" || fMeasure == "f") && 
       (tMeasure == "centigrade" || tMeasure == "celsius" || tMeasure == "c") ) {
    // Convert Fahrenheit to Centigrade.
    return (val - 32) * 5/9;
  } else {
    trace ("Invalid conversion type from " + fMeasure + " to " + tMeasure);
    return NaN;
  }
};

Here are examples of how to use this function:

trace(Math.convertTemperature ("Centigrade", "Fahrenheit", 0));   // Displays: 32
trace(Math.convertTemperature ("c", "f", 0));                     // Displays: 32
trace(Math.convertTemperature ("fahrenheit", "centigrade", 212)); // Displays: 100
trace(Math.convertTemperature ("fahrenheit", "celsius", 212));    // Displays: 100

You could modify the preceding function to also support degrees Kelvin. However, if you support more than two units of measure, the number of possible permutations (and the number of required else if clauses) multiplies rapidly. In such a case, you can convert all values to an interim unit of measurement to reduce the number of transformations required. For example, you can convert all temperatures to and from Centigrade, as follows:

Math.convertToCentigrade = function (fMeasure, val) {
  fMeasure = fMeasure.toLowerCase(  );
  if (fMeasure == "kelvin" || fMeasure == "k") {
    return (val - 273.15);
  } else if ( fMeasure == "fahrenheit" || fMeasure == "f" ) { 
    return (val - 32) * 5/9;
  } else if (fMeasure == "centigrade" || fMeasure == "celsius" || fMeasure == "c") {
    return val;
  } else {
    return NaN;
  }
};

Math.convertFromCentigrade = function (tMeasure, val) {
  tMeasure = tMeasure.toLowerCase(  );
  if (tMeasure == "kelvin" || tMeasure == "k") {
    return (val + 273.15);
  } else if ( tMeasure == "fahrenheit" || tMeasure == "f" ) {
    return (val * 9/5) + 32;
  } else if (tMeasure == "centigrade" || tMeasure == "celsius" || tMeasure == "c") {
    return val;
  } else {
    return NaN;
  }
};

This allows our Math.convertTemperature( ) method to be simplified, as follows:

Math.convertTemperature = function (fMeasure, tMeasure, val) {
  var centigradeVal = Math.convertToCentigrade (fMeasure, val);
  return Math.convertFromCentigrade (tMeasure, centigradeVal );
};

Here are examples of how to use this function:

trace(Math.convertTemperature ("centigrade", "Kelvin", 0));   // Displays: 273.15
trace(Math.convertTemperature ("k", "f", 0));                 // Displays: -459.67
trace(Math.convertTemperature ("fahrenheit", "kelvin", 212)); // Displays: 373.15
trace(Math.convertTemperature ("K", "celsius", 0));           // Displays: -273.15

Or, if you prefer, you could write single-purpose functions, such as Math.fahrToCent( ), Math.centToFahr( ), and Math.fahrToKelvin( ), that simply accept the value to convert.

Here is another function that converts between pounds and kilograms using the same structure shown earlier:

Math.convertWeights = function (fMeasure, tMeasure, val) {
  if (fMeasure == "pounds" && tMeasure == "kilograms") {
    return val / 2.2;
  } else if (fMeasure == "kilograms" && tMeasure == "pounds") {
    return val * 2.2;
  } else {
    return "invalid conversion type";
  }
};

Here are some examples of its use:

trace(Math.convertWeights ("pounds", "kilograms", 0));      // Displays: 0
trace(Math.convertWeights ("kilograms", "pounds", 100));    // Displays: 220

You can add support for conversion to other units of weight by inserting additional else if statements following the same pattern. Or you can use the technique demonstrated for temperature, in which all values are first converted to a common unit.

5.15.4 See Also

For an example of using a hardcoded function to perform a single type of unit conversion, refer to Recipe 5.12, which includes a function to convert angles from degrees to radians and another function that does the opposite.

    [ Team LiB ] Previous Section Next Section