/*
This code is a a heavily modified version of Numbers from Rich Hickeys clojure core, see Numbers.java for copyright
*/
package com.googlecode.totallylazy.numbers;
import java.math.BigDecimal;
import java.math.BigInteger;
import static java.math.BigDecimal.ONE;
public final class BigDecimalOperators implements Operators<BigDecimal> {
public static BigDecimalOperators Instance = new BigDecimalOperators();
private BigDecimalOperators() {}
public final Class<BigDecimal> forClass() {
return BigDecimal.class;
}
public final int priority() {
return 4;
}
@Override
public Number absolute(BigDecimal value) {
return value.abs();
}
public final Number negate(BigDecimal value) {
return value.negate();
}
public final Number increment(BigDecimal value) {
return value.add(ONE);
}
public final Number decrement(BigDecimal value) {
return value.subtract(ONE);
}
public final boolean isZero(BigDecimal value) {
return value.signum() == 0;
}
public final boolean isPositive(BigDecimal value) {
return value.signum() > 0;
}
public final boolean isNegative(BigDecimal value) {
return value.signum() < 0;
}
public final boolean equalTo(Number x, Number y) {
return x.equals(decimal(y));
}
public final boolean lessThan(Number x, Number y) {
return decimal(x).compareTo(decimal(y)) < 0;
}
public final Number add(Number x, Number y) {
return decimal(x).add(decimal(y));
}
public final Number multiply(Number x, Number y) {
return decimal(x).multiply(decimal(y));
}
public final Number divide(Number x, Number y) {
return decimal(x).divide(decimal(y));
}
public final Number quotient(Number x, Number y) {
return decimal(x).divideToIntegralValue(decimal(y));
}
public final Number remainder(Number x, Number y) {
return decimal(x).remainder(decimal(y));
}
public static BigDecimal decimal(Number number) {
if (number instanceof Ratio)
return ((Ratio) number).decimalValue();
if (number instanceof BigDecimal)
return (BigDecimal) number;
if (number instanceof BigInteger)
return new BigDecimal((BigInteger) number);
if (number instanceof Float)
return BigDecimal.valueOf((Float) number);
if (number instanceof Double)
return BigDecimal.valueOf((Double) number);
return BigDecimal.valueOf(number.longValue());
}
public static Number rationalize(BigDecimal number) {
BigInteger unscaled = number.unscaledValue();
int scale = number.scale();
if (scale < 0) {
return unscaled.multiply(BigInteger.TEN.pow(-scale));
}
return unscaled.divide(BigInteger.TEN.pow(scale));
}
}