001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3.math;
018
019import java.util.Objects;
020
021import org.apache.commons.lang3.Validate;
022
023/**
024 * Provides IEEE-754r variants of NumberUtils methods.
025 *
026 * <p>
027 * See: <a href="https://en.wikipedia.org/wiki/IEEE_754r">https://en.wikipedia.org/wiki/IEEE_754r</a>
028 * </p>
029 *
030 * @since 2.4
031 */
032public class IEEE754rUtils {
033
034     /**
035     * Returns the maximum value in an array.
036     *
037     * @param array  An array, must not be null or empty.
038     * @return The maximum value in the array.
039     * @throws NullPointerException Thrown if {@code array} is {@code null}.
040     * @throws IllegalArgumentException Thrown if {@code array} is empty.
041     * @since 3.4 Changed signature from max(double[]) to max(double...)
042     */
043    public static double max(final double... array) {
044        Objects.requireNonNull(array, "array");
045        Validate.isTrue(array.length != 0, "Array cannot be empty.");
046
047        // Finds and returns max
048        double max = array[0];
049        for (int j = 1; j < array.length; j++) {
050            max = max(array[j], max);
051        }
052
053        return max;
054    }
055
056    /**
057     * Gets the maximum of two {@code double} values.
058     *
059     * <p>
060     * NaN is only returned if all numbers are NaN as per IEEE-754r.
061     * </p>
062     *
063     * @param a  value 1.
064     * @param b  value 2.
065     * @return  the largest of the values.
066     */
067    public static double max(final double a, final double b) {
068        if (Double.isNaN(a)) {
069            return b;
070        }
071        if (Double.isNaN(b)) {
072            return a;
073        }
074        return Math.max(a, b);
075    }
076
077    /**
078     * Gets the maximum of three {@code double} values.
079     *
080     * <p>
081     * NaN is only returned if all numbers are NaN as per IEEE-754r.
082     * </p>
083     *
084     * @param a  value 1.
085     * @param b  value 2.
086     * @param c  value 3.
087     * @return  the largest of the values.
088     */
089    public static double max(final double a, final double b, final double c) {
090        return max(max(a, b), c);
091    }
092
093    /**
094     * Returns the maximum value in an array.
095     *
096     * @param array  An array, must not be null or empty.
097     * @return The maximum value in the array.
098     * @throws NullPointerException Thrown if {@code array} is {@code null}.
099     * @throws IllegalArgumentException Thrown if {@code array} is empty.
100     * @since 3.4 Changed signature from max(float[]) to max(float...)
101     */
102    public static float max(final float... array) {
103        Objects.requireNonNull(array, "array");
104        Validate.isTrue(array.length != 0, "Array cannot be empty.");
105
106        // Finds and returns max
107        float max = array[0];
108        for (int j = 1; j < array.length; j++) {
109            max = max(array[j], max);
110        }
111
112        return max;
113    }
114
115    /**
116     * Gets the maximum of two {@code float} values.
117     *
118     * <p>
119     * NaN is only returned if all numbers are NaN as per IEEE-754r.
120     * </p>
121     *
122     * @param a  value 1.
123     * @param b  value 2.
124     * @return  the largest of the values.
125     */
126    public static float max(final float a, final float b) {
127        if (Float.isNaN(a)) {
128            return b;
129        }
130        if (Float.isNaN(b)) {
131            return a;
132        }
133        return Math.max(a, b);
134    }
135
136    /**
137     * Gets the maximum of three {@code float} values.
138     *
139     * <p>
140     * NaN is only returned if all numbers are NaN as per IEEE-754r.
141     * </p>
142     *
143     * @param a  value 1.
144     * @param b  value 2.
145     * @param c  value 3.
146     * @return  the largest of the values.
147     */
148    public static float max(final float a, final float b, final float c) {
149        return max(max(a, b), c);
150    }
151
152    /**
153     * Returns the minimum value in an array.
154     *
155     * @param array  An array, must not be null or empty.
156     * @return The minimum value in the array.
157     * @throws NullPointerException Thrown if {@code array} is {@code null}.
158     * @throws IllegalArgumentException Thrown if {@code array} is empty.
159     * @since 3.4 Changed signature from min(double[]) to min(double...).
160     */
161    public static double min(final double... array) {
162        Objects.requireNonNull(array, "array");
163        Validate.isTrue(array.length != 0, "Array cannot be empty.");
164
165        // Finds and returns min
166        double min = array[0];
167        for (int i = 1; i < array.length; i++) {
168            min = min(array[i], min);
169        }
170
171        return min;
172    }
173
174    /**
175     * Gets the minimum of two {@code double} values.
176     *
177     * <p>
178     * NaN is only returned if all numbers are NaN as per IEEE-754r.
179     * </p>
180     *
181     * @param a  value 1.
182     * @param b  value 2.
183     * @return  the smallest of the values.
184     */
185    public static double min(final double a, final double b) {
186        if (Double.isNaN(a)) {
187            return b;
188        }
189        if (Double.isNaN(b)) {
190            return a;
191        }
192        return Math.min(a, b);
193    }
194
195    /**
196     * Gets the minimum of three {@code double} values.
197     *
198     * <p>
199     * NaN is only returned if all numbers are NaN as per IEEE-754r.
200     * </p>
201     *
202     * @param a  value 1
203     * @param b  value 2
204     * @param c  value 3
205     * @return  the smallest of the values
206     */
207    public static double min(final double a, final double b, final double c) {
208        return min(min(a, b), c);
209    }
210
211    /**
212     * Returns the minimum value in an array.
213     *
214     * @param array  An array, must not be null or empty.
215     * @return The minimum value in the array.
216     * @throws NullPointerException Thrown if {@code array} is {@code null}.
217     * @throws IllegalArgumentException Thrown if {@code array} is empty.
218     * @since 3.4 Changed signature from min(float[]) to min(float...).
219     */
220    public static float min(final float... array) {
221        Objects.requireNonNull(array, "array");
222        Validate.isTrue(array.length != 0, "Array cannot be empty.");
223
224        // Finds and returns min
225        float min = array[0];
226        for (int i = 1; i < array.length; i++) {
227            min = min(array[i], min);
228        }
229
230        return min;
231    }
232
233    /**
234     * Gets the minimum of two {@code float} values.
235     *
236     * <p>
237     * NaN is only returned if all numbers are NaN as per IEEE-754r.
238     * </p>
239     *
240     * @param a  value 1.
241     * @param b  value 2.
242     * @return  the smallest of the values.
243     */
244    public static float min(final float a, final float b) {
245        if (Float.isNaN(a)) {
246            return b;
247        }
248        if (Float.isNaN(b)) {
249            return a;
250        }
251        return Math.min(a, b);
252    }
253
254    /**
255     * Gets the minimum of three {@code float} values.
256     *
257     * <p>
258     * NaN is only returned if all numbers are NaN as per IEEE-754r.
259     * </p>
260     *
261     * @param a  value 1.
262     * @param b  value 2.
263     * @param c  value 3.
264     * @return  the smallest of the values.
265     */
266    public static float min(final float a, final float b, final float c) {
267        return min(min(a, b), c);
268    }
269
270    /**
271     * Make private in 4.0.
272     *
273     * @deprecated TODO Make private in 4.0.
274     */
275    @Deprecated
276    public IEEE754rUtils() {
277        // empty
278    }
279}