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