For some reason I need to compare two primitives: long and float.
Can I use following code for this?
long a = 111L;
float b = 111.1f
if (a > b) {
...
}
I know, that float and float can be compared to some accuracy with using epsilon value and etc.
But how can I perform comparison for my case more correctly?
Thanks to all.
You can wrap both of them in BigDecimal
and them compare them:
long a = 111L;
float b = 111.1f;
BigDecimal first = new BigDecimal(a);
BigDecimal second = new BigDecimal(b, MathContext.DECIMAL32);
if (first.compareTo(second) > 0) { ... }
In order to understand why we're interested to have both of the operands under the same type, let's dig a bit into JLS 5.6.2 Binary Numeric Promotion:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type
double
, the other is converted todouble
.Otherwise, if either operand is of type
float
, the other is converted tofloat
.Otherwise, if either operand is of type
long
, the other is converted tolong
.Otherwise, both operands are converted to type
int
.
With this we can conclude that for the comparison a > b
the long
operand will be implicitly promoted to float
. This, however, can end up with loss of precision, as stated in JLS 5.1.2 Widening primitive conversion:
A widening conversion of an
int
or along
value tofloat
, or of a long value to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).