package edu.washington.escience.myria.expression; import java.util.Set; import com.google.common.collect.ImmutableSet; import edu.washington.escience.myria.Type; import edu.washington.escience.myria.expression.evaluate.ExpressionOperatorParameter; /** * Divide two operands in an expression tree. The return value is of type {@link Type.INT_TYPE} if both operands are * also INTs, and of type {@link Type.LONG_TYPE} otherwise. */ public class IntDivideExpression extends BinaryExpression { /***/ private static final long serialVersionUID = 1L; /** * This is not really unused, it's used automagically by Jackson deserialization. */ @SuppressWarnings("unused") private IntDivideExpression() {} /** * Divide the two operands together. * * @param left the left operand. * @param right the right operand. */ public IntDivideExpression(final ExpressionOperator left, final ExpressionOperator right) { super(left, right); } /** The types that this expression might output. */ private final Set<Type> validTypes = ImmutableSet.<Type>builder().add(Type.LONG_TYPE).add(Type.INT_TYPE).build(); @Override public Type getOutputType(final ExpressionOperatorParameter parameters) { Type possibleType = checkAndReturnDefaultNumericType(parameters); if (validTypes.contains(possibleType)) { return possibleType; } return Type.LONG_TYPE; } @Override public String getJavaString(final ExpressionOperatorParameter parameters) { Type defaultType = checkAndReturnDefaultNumericType(parameters); if (validTypes.contains(defaultType)) { /* Default type is an Int or Long, so just use Java's default division. */ return getInfixBinaryString("/", parameters); } /* Default type if a Float or Double, so cast in a checked-way to a long. */ return new StringBuilder("com.google.common.math.DoubleMath.roundToLong(") .append(getInfixBinaryString("/", parameters)) .append(", java.math.RoundingMode.DOWN)") .toString(); } }