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