blob: 5ed5c5fc8470e911018582328a889b6c60318f89 [file] [log] [blame]
1 Groovy math
Groovy supports access to all Java math classes and operations. However, in order to make scripting math
operations as intuitive as possible to the end user, the groovy math model supports a 'least surprising'
approach to literal math operations. To do this, groovy uses exact, or decimal math for default calculations.
This means that user computations like:
{code:groovy}
1.1 + 0.1 == 1.2
{code}
will return true rather than false (using float or double types in Java returns a result of 1.2000000000000002).
To support this approach, groovy literals with decimal points are instantiated as java.math.BigDecimal types
rather than binary floating point types (Float, Double). Float and Double types can of course be created explicitly
or via the use of the "F" or "D" suffix on the numeric literal.
While the default behavior is to use decimal math, no attempt is made to preserve this if a binary floating
point number is introduced into an expression (i.e. groovy never automatically promotes a binary floating
point number to a BigDecimal). This is done for two reasons: First, doing so would imply a level of exactness
to a result that is not guaranteed to be exact, and secondly, performance is slightly better under binary floating
point math, so once it is introduced it is kept.
Finally, groovy's math implementation is as close as practical to the Java 1.5 BigDecimal math model
which implements precision based floating point decimal math (ANSI X3.274-1996 and ANSI X3.274-1996/AM 1-2000
(section 7.4).
Therefore, binary operations involving subclasses of java.lang.Number automatically convert their arguments according to
the following matrix (except for division, which is discussed below).
{table}
|__BigDecimal__ |__BigInteger__ |__Double__ |__Float__ |__Long__ |__Integer__
__BigDecimal__ |BigDecimal |BigDecimal |Double |Double |BigDecimal |BigDecimal
__BigInteger__ |BigDecimal |BigInteger |Double |Double |BigInteger |BigInteger
__Double__ |Double |Double |Double |Double |Double |Double
__Float__ |Double |Double |Double |Double |Double |Double
__Long__ |BigDecimal |BigInteger |Double |Double |Long |Long
__Integer__ |BigDecimal |BigInteger |Double |Double |Long |Integer
{table}
Note 1: Byte, Character, and Short arguments are considered to be Integer types for the purposes of this matrix.
Note 2: Division (/) produces a Double result if either operand is either Float or Double and a BigDecimal result
otherwise (both operands are any combination of Integer, Long, BigInteger, or BigDecimal). BigDecimal Division is
performed as follows:
{code:java}
BigDecimal.divide(BigDecimal right, <scale>, BigDecimal.ROUND_HALF_UP)
{code}
where <scale> is MAX(this.scale(), right.scale(), 10).
Finally, the resulting BigDecimal is normalized (trailing zeros are removed).
For example:
{code:groovy}
1/2 == new java.math.BigDecimal("0.5");
1/3 == new java.math.BigDecimal("0.3333333333");
2/3 == new java.math.BigDecimal("0.6666666667");
{code}