    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}