001/*
002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos
003 *
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 *  * Redistributions of source code must retain the above copyright notice,
010 *    this list of conditions and the following disclaimer.
011 *
012 *  * Redistributions in binary form must reproduce the above copyright notice,
013 *    this list of conditions and the following disclaimer in the documentation
014 *    and/or other materials provided with the distribution.
015 *
016 *  * Neither the name of JSR-310 nor the names of its contributors
017 *    may be used to endorse or promote products derived from this software
018 *    without specific prior written permission.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 */
032package org.threeten.bp.jdk8;
033
034/**
035 * A set of utility methods that provide additional functionality for working
036 * with dates and times.
037 * <p>
038 * The contents of this class are likely to be replaced by other methods if and
039 * when JSR-310 is integrated into the JDK.
040 *
041 * <h3>Specification for implementors</h3>
042 * This is a thread-safe utility class.
043 * All returned classes are immutable and thread-safe.
044 */
045public final class Jdk8Methods {
046
047    /**
048     * Private constructor since this is a utility class.
049     */
050    private Jdk8Methods() {
051    }
052
053    //-----------------------------------------------------------------------
054    /**
055     * Safely adds two int values.
056     *
057     * @param a  the first value
058     * @param b  the second value
059     * @return the result
060     * @throws ArithmeticException if the result overflows an int
061     */
062    public static int safeAdd(int a, int b) {
063        int sum = a + b;
064        // check for a change of sign in the result when the inputs have the same sign
065        if ((a ^ sum) < 0 && (a ^ b) >= 0) {
066            throw new ArithmeticException("Addition overflows an int: " + a + " + " + b);
067        }
068        return sum;
069    }
070
071    /**
072     * Safely adds two long values.
073     *
074     * @param a  the first value
075     * @param b  the second value
076     * @return the result
077     * @throws ArithmeticException if the result overflows a long
078     */
079    public static long safeAdd(long a, long b) {
080        long sum = a + b;
081        // check for a change of sign in the result when the inputs have the same sign
082        if ((a ^ sum) < 0 && (a ^ b) >= 0) {
083            throw new ArithmeticException("Addition overflows a long: " + a + " + " + b);
084        }
085        return sum;
086    }
087
088    //-----------------------------------------------------------------------
089    /**
090     * Safely subtracts one int from another.
091     *
092     * @param a  the first value
093     * @param b  the second value to subtract from the first
094     * @return the result
095     * @throws ArithmeticException if the result overflows an int
096     */
097    public static int safeSubtract(int a, int b) {
098        int result = a - b;
099        // check for a change of sign in the result when the inputs have the different signs
100        if ((a ^ result) < 0 && (a ^ b) < 0) {
101            throw new ArithmeticException("Subtraction overflows an int: " + a + " - " + b);
102        }
103        return result;
104    }
105
106    /**
107     * Safely subtracts one long from another.
108     *
109     * @param a  the first value
110     * @param b  the second value to subtract from the first
111     * @return the result
112     * @throws ArithmeticException if the result overflows a long
113     */
114    public static long safeSubtract(long a, long b) {
115        long result = a - b;
116        // check for a change of sign in the result when the inputs have the different signs
117        if ((a ^ result) < 0 && (a ^ b) < 0) {
118            throw new ArithmeticException("Subtraction overflows a long: " + a + " - " + b);
119        }
120        return result;
121    }
122
123    //-----------------------------------------------------------------------
124    /**
125     * Safely multiply one int by another.
126     *
127     * @param a  the first value
128     * @param b  the second value
129     * @return the result
130     * @throws ArithmeticException if the result overflows an int
131     */
132    public static int safeMultiply(int a, int b) {
133        long total = (long) a * (long) b;
134        if (total < Integer.MIN_VALUE || total > Integer.MAX_VALUE) {
135            throw new ArithmeticException("Multiplication overflows an int: " + a + " * " + b);
136        }
137        return (int) total;
138    }
139
140    /**
141     * Safely multiply a long by an int.
142     *
143     * @param a  the first value
144     * @param b  the second value
145     * @return the new total
146     * @throws ArithmeticException if the result overflows a long
147     */
148    public static long safeMultiply(long a, int b) {
149        switch (b) {
150            case -1:
151                if (a == Long.MIN_VALUE) {
152                    throw new ArithmeticException("Multiplication overflows a long: " + a + " * " + b);
153                }
154                return -a;
155            case 0:
156                return 0L;
157            case 1:
158                return a;
159        }
160        long total = a * b;
161        if (total / b != a) {
162            throw new ArithmeticException("Multiplication overflows a long: " + a + " * " + b);
163        }
164        return total;
165    }
166
167    /**
168     * Multiply two values throwing an exception if overflow occurs.
169     *
170     * @param a  the first value
171     * @param b  the second value
172     * @return the new total
173     * @throws ArithmeticException if the result overflows a long
174     */
175    public static long safeMultiply(long a, long b) {
176        if (b == 1) {
177            return a;
178        }
179        if (a == 1) {
180            return b;
181        }
182        if (a == 0 || b == 0) {
183            return 0;
184        }
185        long total = a * b;
186        if (total / b != a || (a == Long.MIN_VALUE && b == -1) || (b == Long.MIN_VALUE && a == -1)) {
187            throw new ArithmeticException("Multiplication overflows a long: " + a + " * " + b);
188        }
189        return total;
190    }
191
192    //-----------------------------------------------------------------------
193    /**
194     * Safely convert a long to an int.
195     *
196     * @param value  the value to convert
197     * @return the int value
198     * @throws ArithmeticException if the result overflows an int
199     */
200    public static int safeToInt(long value) {
201        if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
202            throw new ArithmeticException("Calculation overflows an int: " + value);
203        }
204        return (int) value;
205    }
206
207    //-----------------------------------------------------------------------
208    /**
209     * Returns the floor division.
210     * <p>
211     * This returns {@code 0} for {@code floorDiv(0, 4)}.<br />
212     * This returns {@code -1} for {@code floorDiv(-1, 4)}.<br />
213     * This returns {@code -1} for {@code floorDiv(-2, 4)}.<br />
214     * This returns {@code -1} for {@code floorDiv(-3, 4)}.<br />
215     * This returns {@code -1} for {@code floorDiv(-4, 4)}.<br />
216     * This returns {@code -2} for {@code floorDiv(-5, 4)}.<br />
217     *
218     * @param a  the dividend
219     * @param b  the divisor
220     * @return the floor division
221     */
222    public static long floorDiv(long a, long b) {
223        return (a >= 0 ? a / b : ((a + 1) / b) - 1);
224    }
225
226    /**
227     * Returns the floor modulus.
228     * <p>
229     * This returns {@code 0} for {@code floorMod(0, 4)}.<br />
230     * This returns {@code 1} for {@code floorMod(-1, 4)}.<br />
231     * This returns {@code 2} for {@code floorMod(-2, 4)}.<br />
232     * This returns {@code 3} for {@code floorMod(-3, 4)}.<br />
233     * This returns {@code 0} for {@code floorMod(-4, 4)}.<br />
234     *
235     * @param a  the dividend
236     * @param b  the divisor
237     * @return the floor modulus (positive)
238     */
239    public static long floorMod(long a, long b) {
240        return ((a % b) + b) % b;
241    }
242
243    /**
244     * Returns the floor modulus.
245     * <p>
246     * This returns {@code 0} for {@code floorMod(0, 4)}.<br />
247     * This returns {@code 3} for {@code floorMod(-1, 4)}.<br />
248     * This returns {@code 2} for {@code floorMod(-2, 4)}.<br />
249     * This returns {@code 1} for {@code floorMod(-3, 4)}.<br />
250     * This returns {@code 0} for {@code floorMod(-4, 4)}.<br />
251     * This returns {@code 3} for {@code floorMod(-5, 4)}.<br />
252     *
253     * @param a  the dividend
254     * @param b  the divisor
255     * @return the floor modulus (positive)
256     */
257    public static int floorMod(long a, int b) {
258        return (int) (((a % b) + b) % b);
259    }
260
261    /**
262     * Returns the floor division.
263     * <p>
264     * This returns {@code 1} for {@code floorDiv(3, 3)}.<br />
265     * This returns {@code 0} for {@code floorDiv(2, 3)}.<br />
266     * This returns {@code 0} for {@code floorDiv(1, 3)}.<br />
267     * This returns {@code 0} for {@code floorDiv(0, 3)}.<br />
268     * This returns {@code -1} for {@code floorDiv(-1, 3)}.<br />
269     * This returns {@code -1} for {@code floorDiv(-2, 3)}.<br />
270     * This returns {@code -1} for {@code floorDiv(-3, 3)}.<br />
271     * This returns {@code -2} for {@code floorDiv(-4, 3)}.<br />
272     *
273     * @param a  the dividend
274     * @param b  the divisor
275     * @return the floor division
276     */
277    public static int floorDiv(int a, int b) {
278        return (a >= 0 ? a / b : ((a + 1) / b) - 1);
279    }
280
281    /**
282     * Returns the floor modulus.
283     * <p>
284     * This returns {@code 0} for {@code floorMod(3, 3)}.<br />
285     * This returns {@code 2} for {@code floorMod(2, 3)}.<br />
286     * This returns {@code 1} for {@code floorMod(1, 3)}.<br />
287     * This returns {@code 0} for {@code floorMod(0, 3)}.<br />
288     * This returns {@code 2} for {@code floorMod(-1, 3)}.<br />
289     * This returns {@code 1} for {@code floorMod(-2, 3)}.<br />
290     * This returns {@code 0} for {@code floorMod(-3, 3)}.<br />
291     * This returns {@code 2} for {@code floorMod(-4, 3)}.<br />
292     *
293     * @param a  the dividend
294     * @param b  the divisor
295     * @return the floor modulus (positive)
296     */
297    public static int floorMod(int a, int b) {
298        return ((a % b) + b) % b;
299    }
300
301}