Numbers and Math
Prerequisites: Data types
Groovy's number handling has one big surprise for Java developers: decimal literals are exact.
println 0.1 + 0.2
println 0.1 + 0.2 == 0.3
println 0.1d + 0.2d
0.3
true
0.30000000000000004
0.1 is a BigDecimal, so money and measurements add up the way you
expect. Add a d suffix (or declare a double) when you want fast,
approximate floating-point math.
Arithmetic
println 7 + 2
println 7 - 2
println 7 * 2
println 7 / 2 // division gives a decimal
println 7.intdiv(2) // whole-number division
println 7 % 2 // remainder
println 2 ** 10 // power
println(-7.abs()) // parentheses: minus applies after the call
9
5
14
3.5
3
1
1024
-7
/between two integers gives a BigDecimal, not a truncated integer as in Java. Useintdiv()for whole-number division.**raises to a power.- Careful with a leading minus:
-7.abs()means-(7.abs()).
Number literals
println 1_000_000
println 0xFF
println 0b1010
println 42L.getClass().simpleName
println 42G.getClass().simpleName
println 1.5f.getClass().simpleName
println 2 ** 100
1000000
255
10
Long
BigInteger
Float
1267650600228229401496703205376
Underscores group digits. Suffixes pick a type: L long, G
BigInteger (or BigDecimal for decimals), f float, d double.
Integer powers that overflow become BigInteger automatically.
Rounding and Math
def price = 19.999
println price.setScale(2, java.math.RoundingMode.HALF_UP)
println Math.round(2.5)
println Math.sqrt(16)
println Math.max(3, 9)
println 10.5.toInteger()
printf('%.2f%n', 3.14159)
20.00
3
4.0
9
10
3.14
Math is Java's java.lang.Math, available without an import.
setScale rounds a BigDecimal to a number of decimal places.
Common mistakes
- Expecting
7 / 2to be3— it's3.5. Useintdiv. intarithmetic can still overflow:Integer.MAX_VALUE + 1wraps to a negative number, exactly as in Java. UselongorBigIntegerfor very large values.
Practice
A pizza costs 12.40 and is shared by 3 people. Print each person's share rounded to 2 decimal places, and how many whole pizzas 50 can buy.
Show solution
def share = 12.40 / 3
println share.setScale(2, java.math.RoundingMode.HALF_UP)
println((50 / 12.40).toInteger())
4.13
4
toInteger() drops the decimal part, so 4.03 pizzas become 4 whole ones.