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