177 lines
3.9 KiB
Java
177 lines
3.9 KiB
Java
package carpet.script.value;
|
|
|
|
import carpet.script.exception.InternalExpressionException;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
import static java.lang.Math.abs;
|
|
|
|
public class NumericValue extends Value
|
|
{
|
|
private Double value;
|
|
final static double epsilon = 1024*Double.MIN_VALUE;
|
|
|
|
public static NumericValue asNumber(Value v1)
|
|
{
|
|
if (!(v1 instanceof NumericValue))
|
|
throw new InternalExpressionException("Operand has to be of a numeric type");
|
|
return ((NumericValue) v1);
|
|
}
|
|
|
|
|
|
@Override
|
|
public String getString()
|
|
{
|
|
try
|
|
{
|
|
return BigDecimal.valueOf(value).stripTrailingZeros().toPlainString();
|
|
}
|
|
catch (NumberFormatException exc)
|
|
{
|
|
throw new ArithmeticException("Incorrect number format for "+value);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getPrettyString()
|
|
{
|
|
if (getDouble() == (double)getLong())
|
|
{
|
|
return Long.toString(getLong());
|
|
}
|
|
else
|
|
{
|
|
return String.format("%.3f..", getDouble());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean getBoolean()
|
|
{
|
|
return value != null && abs(value) > epsilon;
|
|
}
|
|
public double getDouble()
|
|
{
|
|
return value;
|
|
}
|
|
public long getLong()
|
|
{
|
|
return (long)(value+epsilon);
|
|
}
|
|
|
|
@Override
|
|
public Value add(Value v)
|
|
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
|
if (v instanceof NumericValue)
|
|
{
|
|
return new NumericValue(getDouble() + ((NumericValue) v).getDouble() );
|
|
}
|
|
return super.add(v);
|
|
}
|
|
public Value subtract(Value v) { // TODO test if definintn add(NumericVlaue) woud solve the casting
|
|
if (v instanceof NumericValue)
|
|
{
|
|
return new NumericValue(getDouble() - (((NumericValue) v).getDouble()));
|
|
}
|
|
return super.subtract(v);
|
|
}
|
|
public Value multiply(Value v)
|
|
{
|
|
if (v instanceof NumericValue)
|
|
{
|
|
return new NumericValue(getDouble() * ((NumericValue) v).getDouble() );
|
|
}
|
|
if (v instanceof ListValue)
|
|
{
|
|
return v.multiply(this);
|
|
}
|
|
return new StringValue(StringUtils.repeat(v.getString(), (int) getLong()));
|
|
}
|
|
public Value divide(Value v)
|
|
{
|
|
if (v instanceof NumericValue)
|
|
{
|
|
return new NumericValue(getDouble() / ((NumericValue) v).getDouble() );
|
|
}
|
|
return super.divide(v);
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
public Value clone()
|
|
{
|
|
return new NumericValue(value);
|
|
}
|
|
|
|
@Override
|
|
public int compareTo(Value o)
|
|
{
|
|
if (o instanceof NullValue)
|
|
{
|
|
return -o.compareTo(this);
|
|
}
|
|
if (o instanceof NumericValue)
|
|
{
|
|
return value.compareTo(((NumericValue) o).getDouble());
|
|
}
|
|
return getString().compareTo(o.getString());
|
|
}
|
|
@Override
|
|
public boolean equals(Value o)
|
|
{
|
|
if (o instanceof NullValue)
|
|
{
|
|
return o.equals(this);
|
|
}
|
|
if (o instanceof NumericValue)
|
|
{
|
|
return !this.subtract(o).getBoolean();
|
|
}
|
|
return super.equals(o);
|
|
}
|
|
|
|
public NumericValue(double value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
public NumericValue(String value)
|
|
{
|
|
this(new BigDecimal(value).doubleValue());
|
|
}
|
|
public NumericValue(long value)
|
|
{
|
|
this.value = (double)value;
|
|
}
|
|
public NumericValue(boolean boolval)
|
|
{
|
|
this(boolval?1.0D:0.0D);
|
|
}
|
|
|
|
@Override
|
|
public int length()
|
|
{
|
|
return Integer.toString(value.intValue()).length();
|
|
}
|
|
|
|
@Override
|
|
public double readNumber()
|
|
{
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public long readInteger()
|
|
{
|
|
return getLong();
|
|
}
|
|
|
|
@Override
|
|
public String getTypeString()
|
|
{
|
|
return "number";
|
|
}
|
|
|
|
}
|