MathUtils { public static double reduce(double a, double period, double offset) { final double p = FastMath.abs(period); return a - p * FastMath.floor((a - offset) / p) - offset; } private  MathUtils(); static int hash(double value); static boolean equals(double x, double y); static int hash(double[] value); static double normalizeAngle(double a, double center); static double reduce(double a,
                                double period,
                                double offset); static byte copySign(byte magnitude, byte sign); static short copySign(short magnitude, short sign); static int copySign(int magnitude, int sign); static long copySign(long magnitude, long sign); static void checkFinite(final double x); static void checkFinite(final double[] val); static void checkNotNull(Object o,
                                    Localizable pattern,
                                    Object ... args); static void checkNotNull(Object o); static final double TWO_PI; static final double PI_SQUARED; }
@Test public void testReduce() { final double period = -12.222; final double offset = 13; final double delta = 1.5; double orig = offset + 122456789 * period + delta; double expected = delta; Assert.assertEquals(expected, MathUtils.reduce(orig, period, offset), 1e-7); Assert.assertEquals(expected, MathUtils.reduce(orig, -period, offset), 1e-7); orig = offset - 123356789 * period - delta; expected = FastMath.abs(period) - delta; Assert.assertEquals(expected, MathUtils.reduce(orig, period, offset), 1e-6); Assert.assertEquals(expected, MathUtils.reduce(orig, -period, offset), 1e-6); orig = offset - 123446789 * period + delta; expected = delta; Assert.assertEquals(expected, MathUtils.reduce(orig, period, offset), 1e-6); Assert.assertEquals(expected, MathUtils.reduce(orig, -period, offset), 1e-6); Assert.assertTrue(Double.isNaN(MathUtils.reduce(orig, Double.NaN, offset))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(Double.NaN, period, offset))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(orig, period, Double.NaN))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(orig, period, Double.POSITIVE_INFINITY))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(Double.POSITIVE_INFINITY, period, offset))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(orig, Double.POSITIVE_INFINITY, offset))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(orig, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(Double.POSITIVE_INFINITY, period, Double.POSITIVE_INFINITY))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, offset))); Assert.assertTrue(Double.isNaN(MathUtils.reduce(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY))); }