/* 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 com.googlecode.totallylazy.annotations.tailrec; import static java.lang.Integer.MAX_VALUE; import static java.lang.Integer.MIN_VALUE; import static java.math.BigInteger.valueOf; public final class IntegerOperators implements Operators<Integer>, IntegralOperators { public static IntegerOperators Instance = new IntegerOperators(); private IntegerOperators() {} public final Class<Integer> forClass() { return Integer.class; } public final int priority() { return 0; } @Override public Number absolute(Integer value) { return Math.abs(value); } public final Number negate(Integer value) { if (value > MIN_VALUE) return -value; return -((long) value); } public final Number increment(Integer value) { if (value < MAX_VALUE) return value + 1; return (long) value + 1; } public final Number decrement(Integer value) { if (value > MIN_VALUE) return value - 1; return (long) value - 1; } public final boolean isZero(Integer value) { return value == 0; } public final boolean isPositive(Integer value) { return value > 0; } public final boolean isNegative(Integer value) { return value < 0; } public final boolean equalTo(Number x, Number y) { return x.intValue() == y.intValue(); } public final boolean lessThan(Number x, Number y) { return x.intValue() < y.intValue(); } public final Number add(Number x, Number y) { long ret = x.longValue() + y.longValue(); if (ret <= MAX_VALUE && ret >= MIN_VALUE) return (int) ret; return ret; } public final Number multiply(Number x, Number y) { long ret = x.longValue() * y.longValue(); if (ret <= MAX_VALUE && ret >= MIN_VALUE) return (int) ret; return ret; } @Override public final Number gcd(Number x, Number y) { return gcd(x.intValue(), y.intValue()); } public Number lcm(Number x, Number y) { return lcm(x.intValue(), y.intValue()); } public static int lcm(int x, int y) { if(x == 0 || y == 0) return 0; return Math.abs(y * quotient(x, gcd(x, y))); } @tailrec public static int gcd(int x, int y) { if (y == 0) return x; return gcd(y, x % y); } public final Number divide(Number x, Number y) { int n = x.intValue(); int val = y.intValue(); int gcd = gcd(n, val); if (gcd == 0) return 0; n = n / gcd; int d = val / gcd; if (d == 1) return n; if (d < 0) { n = -n; d = -d; } return new Ratio(valueOf(n), valueOf(d)); } public final Number quotient(Number x, Number y) { return quotient(x.intValue(), y.intValue()); } public static int quotient(int x, int y) { return x / y; } public final Number remainder(Number x, Number y) { return x.intValue() % y.intValue(); } }