package org.dcache.util; public class MathUtils { /** * Return the absolute value of an integer, modulo some other integer. * This is similar to the naive {@code Math.abs(value) % modulo} except it handles * the case when value is Integer.MIN_VALUE correctly. */ public static int absModulo(int value, int modulo) { return Math.abs(value % modulo); } /** * Implements long addition, treating MAX_VALUE and MIN_VALUE as positive * and negative infinity respectively. Semantics are similar to Double * arithmetic. Overflow results in positive infinity, underflow in * negative infinity. * * There is no NaN, thus addition of negative and positive throws * ArithmeticException instead. * * Note that MAX_VALUE != -MIN_VALUE, which is a derivation from Double * arithmetic. * * @throws ArithmeticException when adding MIN_VALUE and MAX_VALUE */ public static long addWithInfinity(long a, long b) { if (a == Long.MIN_VALUE && b == Long.MAX_VALUE || a == Long.MAX_VALUE && b == Long.MIN_VALUE) { throw new ArithmeticException("NaN"); } if (a == Long.MAX_VALUE || b == Long.MAX_VALUE) { return Long.MAX_VALUE; } if (a == Long.MIN_VALUE || b == Long.MIN_VALUE) { return Long.MIN_VALUE; } long result = a + b; if ((a ^ b) < 0 | (a ^ result) >= 0) { return result; } return (a < 0) ? Long.MIN_VALUE : Long.MAX_VALUE; } /** * Implements long subtraction, treating MAX_VALUE and MIN_VALUE as * positive and negative infinity respectively. Semantics are similar * to Double arithmetic. Overflow results in positive infinity, underflow * in negative infinity. * * There is no NaN, thus addition of negative and positive throws * ArithmeticException instead. * * Note that MAX_VALUE != -MIN_VALUE, which is a derivation from Double * arithmetic. * * @throws ArithmeticException when subtracting MIN_VALUE from MIN_VALUE * or MAX_VALUE from MAX_VALUE */ public static long subWithInfinity(long a, long b) { if (a == Long.MAX_VALUE && b == Long.MAX_VALUE || a == Long.MIN_VALUE && b == Long.MIN_VALUE) { throw new ArithmeticException("NaN"); } if (a == Long.MIN_VALUE || b == Long.MAX_VALUE) { return Long.MIN_VALUE; } if (a == Long.MAX_VALUE || b == Long.MIN_VALUE) { return Long.MAX_VALUE; } long result = a - b; if ((a ^ b) >= 0 | (a ^ result) >= 0) { return result; } return (a < 0) ? Long.MIN_VALUE : Long.MAX_VALUE; } }