in src/main/java/org/apache/commons/jexl3/JexlArithmetic.java [1233:1276]
public Object mod(final Object left, final Object right) {
if (left == null && right == null) {
return controlNullNullOperands(JexlOperator.MOD);
}
final boolean strictCast = isStrict(JexlOperator.MOD);
// if both (non-null) args fit as long
final Number ln = asLongNumber(strictCast, left);
final Number rn = asLongNumber(strictCast, right);
if (ln != null && rn != null) {
final long x = ln.longValue();
final long y = rn.longValue();
if (y == 0L) {
throw new ArithmeticException("%");
}
final long result = x % y;
return narrowLong(left, right, result);
}
// 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);
if (BigDecimal.ZERO.equals(r)) {
throw new ArithmeticException("%");
}
return l.remainder(r, getMathContext());
}
// 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);
if (r == 0.0) {
throw new ArithmeticException("%");
}
return l % r;
}
// otherwise treat as BigInteger
final BigInteger l = toBigInteger(strictCast, left);
final BigInteger r = toBigInteger(strictCast, right);
if (BigInteger.ZERO.equals(r)) {
throw new ArithmeticException("%");
}
final BigInteger result = l.mod(r);
return narrowBigInteger(left, right, result);
}