Trying out floating point arithmetic in Groovy. Have no idea why/how/what groovy is doing behind the scenes to cause these different types of behaviors?
double point2 = 0.2
double point1 = 0.1
double point3 = 0.3
assert point2 + point1 == point3 // false, as expected
| | | | |
0.2 | 0.1 | 0.3
| false
0.30000000000000004
float point2 = 0.2
float point1 = 0.1
float point3 = 0.3
assert point2 + point1 == point3 // false, as expected
| | | | |
0.2 | 0.1 | 0.3
| false
0.30000000447034836
def point2 = 0.2
def point1 = 0.1
def point3 = 0.3
assert point2 + point1 == point3 // this returns true
assert 0.2 + 0.1 == 0.3 // this returns true
I thought it had to do with BigDecimal but then I tried this.
BigDecimal point2 = 0.2
BigDecimal point1 = 0.1
BigDecimal point3 = 0.3
float point4 = 0.4
assert point1 + point3 == point4
| | | | |
0.1 | 0.3 | 0.4
0.4 false
What is causing this behavior?
In computing, floating-point arithmetic (FP) is arithmetic using formulaic representation of real numbers as an approximation to support a trade-off between range and precision.
Floating-point numbers are used to represent numbers that have a decimal point in them (such as 5.3 or 99.234). Whole numbers can also be represented, but as a floating point, the number 5 is actually 5.0. In Java, floating-point numbers are represented by the types float and double.
The main cause of the error in floating point division is the division algorithms used to calculate the quotient. Most computer systems calculate division using multiplication by an inverse, mainly in Z=X/Y , Z = X * (1/Y) .
your def
:s there are BigDecimals
groovy:000> p1 = 0.1
===> 0.1
groovy:000> p1.getClass()
===> class java.math.BigDecimal
And equals
fails for comparsion between BigDecimal and the native float/double
groovy:000> p1.equals(0.1f)
===> false
groovy:000> p1.equals(0.1)
===> true
groovy:000> p1==0.1f
===> false
groovy:000> p1==0.1
===> true
Not sure yet, why ==
works for [Dd]ouble.
groovy:000> p1.equals(0.1d)
===> false
groovy:000> p1==0.1d
===> true
My guess would be, that it's burried in DefaultTypeTransformation.compareToWithEqualityCheck
. As both sides are Number:s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With