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