Groovy

Using Groovy

Language Guide

Groovy Features

Modules

Examples

Useful Links

IDE Support

Support

Community

Developers

Tools we use

IntelliJ IDEA
YourKit profiler

Feeds


Site
News
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 for script programmers. To do this, groovy uses exact, or decimal math for default calculations.

This means that user computations like:

1.1 + 0.1 == 1.2

will return true rather than false (using float or double types in Java returns a result of 1.2000000000000002).

Numeric literals

To support the 'least surprising' 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 a suffix (see table below). Exponential notation is supported for decimal types (BigDecimal, Double Float) with or without a signed
exponent (1.23e-23). Hexadecimal and octal literals are also supported. Hexadecimal numbers are specified
in the typical format of "0x" followed by hex digits (e.g. 0x77).

Integral numeric literals (those without a decimal point) which begin with a 0 are treated as octal. Both octal and hexadecimal literals may have an integral suffix (G,L,I). Integral numeric literals without a suffix will be the smallest type into which the value will fit (Integer, Long, or BigInteger). See the numeric literal grammar at the end of this page for more details on syntax.

Type Suffix
BigInteger G
Long L
Integer I
BigDecimal G
Double D
Float F

Examples:

assert 42I == new Integer("42");
assert 123L == new Long("123");
assert 2147483648 == new Long("2147483648"); //Long type used, value too large for an Integer
assert 456G == new java.math.BigInteger("456");
assert 123.45 == new java.math.BigDecimal("123.45"); //default BigDecimal type used
assert 1.200065D == new Double("1.200065");
assert 1.234F == new Float("1.234");
assert 1.23E23D == new Double("1.23E23");

Math operations

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).


  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

Note - Byte, Character, and Short arguments are considered to be Integer types for the purposes of this matrix.

Division

The division operators "/" and "/=" produce 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:


BigDecimal.divide(BigDecimal right, <scale>, BigDecimal.ROUND_HALF_UP)

where <scale> is MAX(this.scale(), right.scale(), 10).Finally, the resulting BigDecimal is normalized (trailing zeros are removed).
For example:

1/2 == new java.math.BigDecimal("0.5");
1/3 == new java.math.BigDecimal("0.3333333333");
2/3 == new java.math.BigDecimal("0.6666666667");

Integer Division can be performed on the integral types by using the "\" and "\=" operators. Note that since backslash is the Java escape character, Groovy scripts specified as literal strings need to escape this operator:

" x = 8\\3 "

Numeric literal grammar

IntegerLiteral: 
	Base10IntegerLiteral 
	HexIntegerLiteral	 
	OctalIntegerLiteral  

Base10IntegerLiteral: 
	Base10Numeral IntegerTypeSuffix (optional) 

HexIntegerLiteral: 
	HexNumeral IntegerTypeSuffix (optional) 

OctalIntegerLiteral:	
	OctalNumeral IntegerTypeSuffix (optional) 

IntegerTypeSuffix: one of 
	i I l L g G

Base10Numeral: 
	0 
	NonZeroDigit Digits (optional) 

Digits: 
	Digit
	Digits Digit 

Digit: 
	0
	NonZeroDigit

NonZeroDigit: one of
	\1 2 3 4 5 6 7 8 9

HexNumeral:
	0 x HexDigits
	0 X HexDigits

HexDigits:
	HexDigit
	HexDigit HexDigits

HexDigit: one of
	0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

OctalNumeral:
	0 OctalDigits

OctalDigits:
	OctalDigit
	OctalDigit OctalDigits

OctalDigit: one of
	0 1 2 3 4 5 6 7


DecimalPointLiteral:
	Digits . Digits ExponentPart (optional) DecimalTypeSuffix (optional)
	. Digits ExponentPart (optional) DecimalTypeSuffix (optional)
	Digits ExponentPart DecimalTypeSuffix (optional)
	Digits ExponentPart (optional) DecimalTypeSuffix (optional) 

ExponentPart:
	ExponentIndicator SignedInteger

ExponentIndicator: one of
	e E

SignedInteger:
	Signopt Digits

Sign: one of
	+ -

DecimalTypeSuffix: one of
	f F d D g G