package org.araqne.logdb.query.expr;
import java.util.List;
import org.araqne.logdb.QueryContext;
import org.araqne.logdb.Row;
public class Floor extends FunctionExpression {
private Expression expr;
private Expression digitExpr;
public Floor(QueryContext ctx, List<Expression> exprs) {
super("floor", exprs, 1);
this.expr = exprs.get(0);
if (exprs.size() > 1) {
this.digitExpr = exprs.get(1);
}
}
@Override
public Object eval(Row map) {
Object o = expr.eval(map);
if (o == null)
return null;
// calculate digits
long digit = 0;
if (digitExpr != null) {
Object d = digitExpr.eval(map);
if (d instanceof Long)
digit = (Long)d;
else if (d instanceof Integer)
digit = (Integer)d;
else if (d instanceof Short)
digit = (Short)d;
else
return null;
}
// caculate value
double value = 0;
if (o instanceof Double) {
value = (Double) o;
} else if (o instanceof Float) {
value = (Float) o;
} else if (o instanceof Integer) {
// if round is unnecessary, return input
if (digit >= 0)
return o;
value = (Integer) o;
} else if (o instanceof Long) {
// if round is unnecessary, return input
if (digit >= 0)
return o;
value = (Long) o;
} else if (o instanceof Short) {
// if round is unnecessary, return input
if (digit >= 0)
return o;
value = (Short) o;
} else
return null;
// use long for preserving precision
long m = 1;
if (digit != 0)
m = (long)Math.pow(10, Math.abs(digit));
if (digit <= 0) {
return ((long)Math.floor(value / m)) * m;
}
else
return Math.floor(value * m) / m;
}
}