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 *      http://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>See: <a href="https://en.wikipedia.org/wiki/IEEE_754r">https://en.wikipedia.org/wiki/IEEE_754r</a></p>
027 *
028 * @since 2.4
029 */
030public class IEEE754rUtils {
031
032     /**
033     * Returns the minimum value in an array.
034     *
035     * @param array  an array, must not be null or empty
036     * @return the minimum value in the array
037     * @throws NullPointerException if {@code array} is {@code null}
038     * @throws IllegalArgumentException if {@code array} is empty
039     * @since 3.4 Changed signature from min(double[]) to min(double...)
040     */
041    public static double min(final double... array) {
042        Objects.requireNonNull(array, "array");
043        Validate.isTrue(array.length != 0, "Array cannot be empty.");
044
045        // Finds and returns min
046        double min = array[0];
047        for (int i = 1; i < array.length; i++) {
048            min = min(array[i], min);
049        }
050
051        return min;
052    }
053
054    /**
055     * Returns the minimum value in an array.
056     *
057     * @param array  an array, must not be null or empty
058     * @return the minimum value in the array
059     * @throws NullPointerException if {@code array} is {@code null}
060     * @throws IllegalArgumentException if {@code array} is empty
061     * @since 3.4 Changed signature from min(float[]) to min(float...)
062     */
063    public static float min(final float... array) {
064        Objects.requireNonNull(array, "array");
065        Validate.isTrue(array.length != 0, "Array cannot be empty.");
066
067        // Finds and returns min
068        float min = array[0];
069        for (int i = 1; i < array.length; i++) {
070            min = min(array[i], min);
071        }
072
073        return min;
074    }
075
076    /**
077     * Gets the minimum of three {@code double} values.
078     *
079     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
080     *
081     * @param a  value 1
082     * @param b  value 2
083     * @param c  value 3
084     * @return  the smallest of the values
085     */
086    public static double min(final double a, final double b, final double c) {
087        return min(min(a, b), c);
088    }
089
090    /**
091     * Gets the minimum of two {@code double} values.
092     *
093     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
094     *
095     * @param a  value 1
096     * @param b  value 2
097     * @return  the smallest of the values
098     */
099    public static double min(final double a, final double b) {
100        if (Double.isNaN(a)) {
101            return b;
102        }
103        if (Double.isNaN(b)) {
104            return a;
105        }
106        return Math.min(a, b);
107    }
108
109    /**
110     * Gets the minimum of three {@code float} values.
111     *
112     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
113     *
114     * @param a  value 1
115     * @param b  value 2
116     * @param c  value 3
117     * @return  the smallest of the values
118     */
119    public static float min(final float a, final float b, final float c) {
120        return min(min(a, b), c);
121    }
122
123    /**
124     * Gets the minimum of two {@code float} values.
125     *
126     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
127     *
128     * @param a  value 1
129     * @param b  value 2
130     * @return  the smallest of the values
131     */
132    public static float min(final float a, final float b) {
133        if (Float.isNaN(a)) {
134            return b;
135        }
136        if (Float.isNaN(b)) {
137            return a;
138        }
139        return Math.min(a, b);
140    }
141
142    /**
143     * Returns the maximum value in an array.
144     *
145     * @param array  an array, must not be null or empty
146     * @return the minimum value in the array
147     * @throws NullPointerException if {@code array} is {@code null}
148     * @throws IllegalArgumentException if {@code array} is empty
149     * @since 3.4 Changed signature from max(double[]) to max(double...)
150     */
151    public static double max(final double... array) {
152        Objects.requireNonNull(array, "array");
153        Validate.isTrue(array.length != 0, "Array cannot be empty.");
154
155        // Finds and returns max
156        double max = array[0];
157        for (int j = 1; j < array.length; j++) {
158            max = max(array[j], max);
159        }
160
161        return max;
162    }
163
164    /**
165     * Returns the maximum value in an array.
166     *
167     * @param array  an array, must not be null or empty
168     * @return the minimum value in the array
169     * @throws NullPointerException if {@code array} is {@code null}
170     * @throws IllegalArgumentException if {@code array} is empty
171     * @since 3.4 Changed signature from max(float[]) to max(float...)
172     */
173    public static float max(final float... array) {
174        Objects.requireNonNull(array, "array");
175        Validate.isTrue(array.length != 0, "Array cannot be empty.");
176
177        // Finds and returns max
178        float max = array[0];
179        for (int j = 1; j < array.length; j++) {
180            max = max(array[j], max);
181        }
182
183        return max;
184    }
185
186    /**
187     * Gets the maximum of three {@code double} values.
188     *
189     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
190     *
191     * @param a  value 1
192     * @param b  value 2
193     * @param c  value 3
194     * @return  the largest of the values
195     */
196    public static double max(final double a, final double b, final double c) {
197        return max(max(a, b), c);
198    }
199
200    /**
201     * Gets the maximum of two {@code double} values.
202     *
203     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
204     *
205     * @param a  value 1
206     * @param b  value 2
207     * @return  the largest of the values
208     */
209    public static double max(final double a, final double b) {
210        if (Double.isNaN(a)) {
211            return b;
212        }
213        if (Double.isNaN(b)) {
214            return a;
215        }
216        return Math.max(a, b);
217    }
218
219    /**
220     * Gets the maximum of three {@code float} values.
221     *
222     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
223     *
224     * @param a  value 1
225     * @param b  value 2
226     * @param c  value 3
227     * @return  the largest of the values
228     */
229    public static float max(final float a, final float b, final float c) {
230        return max(max(a, b), c);
231    }
232
233    /**
234     * Gets the maximum of two {@code float} values.
235     *
236     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r.</p>
237     *
238     * @param a  value 1
239     * @param b  value 2
240     * @return  the largest of the values
241     */
242    public static float max(final float a, final float b) {
243        if (Float.isNaN(a)) {
244            return b;
245        }
246        if (Float.isNaN(b)) {
247            return a;
248        }
249        return Math.max(a, b);
250    }
251
252}