in src/main/java/org/apache/commons/jexl3/JexlArithmetic.java [984:1046]
public Number narrowNumber(final Number original, final Class<?> narrow) {
if (original == null) {
return null;
}
Number result = original;
if (original instanceof BigDecimal) {
final BigDecimal bigd = (BigDecimal) original;
// if it is bigger than a double, it can not be narrowed
if (bigd.compareTo(BIGD_DOUBLE_MAX_VALUE) > 0
|| bigd.compareTo(BIGD_DOUBLE_MIN_VALUE) < 0) {
return original;
}
try {
final long l = bigd.longValueExact();
// coerce to int when possible (int being so often used in method parms)
if (narrowAccept(narrow, Integer.class)
&& l <= Integer.MAX_VALUE
&& l >= Integer.MIN_VALUE) {
return (int) l;
}
if (narrowAccept(narrow, Long.class)) {
return l;
}
} catch (final ArithmeticException xa) {
// ignore, no exact value possible
}
}
if (original instanceof Double || original instanceof Float) {
final double value = original.doubleValue();
if (narrowAccept(narrow, Float.class)
&& value <= Float.MAX_VALUE
&& value >= Float.MIN_VALUE) {
result = result.floatValue();
}
// else it fits in a double only
} else {
if (original instanceof BigInteger) {
final BigInteger bigi = (BigInteger) original;
// if it is bigger than a Long, it can not be narrowed
if (bigi.compareTo(BIGI_LONG_MAX_VALUE) > 0
|| bigi.compareTo(BIGI_LONG_MIN_VALUE) < 0) {
return original;
}
}
final long value = original.longValue();
if (narrowAccept(narrow, Byte.class)
&& value <= Byte.MAX_VALUE
&& value >= Byte.MIN_VALUE) {
// it will fit in a byte
result = (byte) value;
} else if (narrowAccept(narrow, Short.class)
&& value <= Short.MAX_VALUE
&& value >= Short.MIN_VALUE) {
result = (short) value;
} else if (narrowAccept(narrow, Integer.class)
&& value <= Integer.MAX_VALUE
&& value >= Integer.MIN_VALUE) {
result = (int) value;
}
// else it fits in a long
}
return result;
}