in src/main/java/org/apache/commons/jexl3/JexlArithmetic.java [1228:1274]
public Object add(final Object left, final Object right) {
if (left == null && right == null) {
return controlNullNullOperands(JexlOperator.ADD);
}
final boolean strconcat = strict
? left instanceof String || right instanceof String
: left instanceof String && right instanceof String;
if (!strconcat) {
try {
// if both (non-null) args fit as long
final Number ln = asLongNumber(left);
final Number rn = asLongNumber(right);
if (ln != null && rn != null) {
final long x = ln.longValue();
final long y = rn.longValue();
final long result = x + y;
// detect overflow, see java8 Math.addExact
if (((x ^ result) & (y ^ result)) < 0) {
return BigInteger.valueOf(x).add(BigInteger.valueOf(y));
}
return narrowLong(left, right, result);
}
final boolean strictCast = isStrict(JexlOperator.ADD);
// if either are bigdecimal use that type
if (left instanceof BigDecimal || right instanceof BigDecimal) {
final BigDecimal l = toBigDecimal(strictCast, left);
final BigDecimal r = toBigDecimal(strictCast, right);
final BigDecimal result = l.add(r, getMathContext());
return narrowBigDecimal(left, right, result);
}
// if either are floating point (double or float) use double
if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
final double l = toDouble(strictCast, left);
final double r = toDouble(strictCast, right);
return l + r;
}
// otherwise treat as (big) integers
final BigInteger l = toBigInteger(strictCast, left);
final BigInteger r = toBigInteger(strictCast, right);
final BigInteger result = l.add(r);
return narrowBigInteger(left, right, result);
} catch (final ArithmeticException nfe) {
// ignore and continue in sequence
}
}
return (left == null ? "" : toString(left)).concat(right == null ? "" : toString(right));
}