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