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 to
double
.
Otherwise, if either operand is of type float
, the other is converted
to float
.
Otherwise, if either operand is of type long
, the other is converted
to long
.
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 a long
value to float
, 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).