Working with Basic Decimal Numbers

Just as Integers have two variants, there are two variants of Decimal attributes in BOM classes: Floating Point and Fixed Point. The sub-type to use is selected in the Advanced Property sheet for the attribute, just as the Integer attributes in Signed Integers.

The Floating Point variant can store:

  • Negative numbers between -1.79769E+308 and -2.225E-307
  • 0
  • Positive values between 2.225E-307 and 1.79769E+308.

The Floating Point variant stores numbers with 16 significant digits of accuracy. However, it should not be used for storing values that have to be exact, for example, money amounts. Rounding errors may occur, especially if large amounts are involved.

The Fixed Point variant can store numbers to an arbitrarily large size, and can perform arithmetic using many different types of rounding as required. However, the downside is that the Fixed Point attributes are implemented as BigDecimal objects, which, like the BigInteger objects in the previous section, have to be manipulated using their methods (add(), subtract, divide(), multiple(), and so on.) instead of the normal arithmetic operators ("+", "-", "/", "*", and so on.).

For more information about the Fixed Point decimal attributes, see Advanced Scripting Examples.

Here are some examples that demonstrate how decimals can be used in scripts. For Floating Point decimals, assuming that averageWeight is now a Floating Point decimal attribute of the team Data Field, we can write:

var totalKgs = 0.0;
var teamSize = 0;
for (var iterator = team.members.listIterator(); iterator.hasNext(); )
{
     var member = iterator.next();
     totalKgs   = totalKgs + member.weightKgs;
     teamSize   = teamSize + 1;
}
team.averageWeight = totalKgs / teamSize;

As in the integer example, the two additional lines can be abbreviated as:

totalKgs += member.weightKgs;
teamSize++;

To compare Floating Point decimal values, use the standard "<", "<="," ==", "!=", ">=" and, ">" operators. It is possible that two numbers that appear to be the same may not be equal using the "==" operator due to rounding errors in the way that the numbers are represented. (These operators are the same as for the Signed Integers. For more information about how these operators can be used, see Operators for Comparing Signed Integers.)

As an example of how Floating Point numbers may not be exactly as they seem, the result of the following expression is false due to rounding errors:

(((1/10) * 14) == 1.4)

To get around this problem, the values should be rounded before comparison.

Rounding of Floating Point Decimals can be done using the ScriptUtil.round() method, for example, to convert a number to 3 decimal places you can write:

roundedValue = ScriptUtil.round(value, 3);

This converts 1234.56789 to 1234.568 using HALF_UP rounding. If you wanted to round down, then the Math.floor() method can be used instead of the ScriptUtil.round() method:

roundedValue = Math.floor(value*1000)/1000;

The ScriptUtil.round() method can also be used to round to a power of 10, for example, to round to the nearest 100, the power of 10 is 2, so use:

roundedValue = ScriptUtil.round(value, -2);

This rounds 1234.56789 to 1200. The Math class provides other methods, for example, log & trig functions and random() and floor() functions. See Math Methods for details.

See also Working with Fixed Decimals (BigDecimal).