All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jn.langx.util.Maths Maven / Gradle / Ivy

Go to download

Java lang extensions for java6+, a supplement to , replacement of a Guava, commons-lang. Core utilities, Collection utilities, IO utilities, Cache, Configuration library ...

There is a newer version: 4.8.2
Show newest version
package com.jn.langx.util;

import com.jn.langx.util.collection.Arrs;
import com.jn.langx.util.collection.Collects;
import com.jn.langx.util.collection.Pipeline;
import com.jn.langx.util.comparator.ComparableComparator;
import com.jn.langx.util.function.Consumer;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class Maths {

    /**
     * 求最大值
     */
    public static int max(int... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.max(array, new ComparableComparator());
    }

    /**
     * 求最大值
     */
    public static float maxFloat(float... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.max(array, new ComparableComparator());
    }

    /**
     * 求最大值
     */
    public static long maxLong(long... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.max(array, new ComparableComparator());
    }

    /**
     * 求最大值
     */
    public static double maxDouble(double... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.max(array, new ComparableComparator());
    }

    /**
     * 求最小值
     */
    public static int min(int... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.min(array, new ComparableComparator());
    }

    /**
     * 求最小值
     */
    public static float minFloat(float... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.min(array, new ComparableComparator());
    }

    /**
     * 求最小值
     */
    public static long minLong(long... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.min(array, new ComparableComparator());
    }

    /**
     * 求最小值
     */
    public static double minDouble(double... array) {
        Preconditions.checkTrue(array.length > 0);
        return Collects.min(array, new ComparableComparator());
    }

    /**
     * Determine if the requested {@code index} and {@code length} will fit within {@code capacity}.
     *
     * @param index    The starting index.
     * @param length   The length which will be utilized (starting from {@code index}).
     * @param capacity The capacity that {@code index + length} is allowed to be within.
     * @return {@code true} if the requested {@code index} and {@code length} will fit within {@code capacity}.
     * {@code false} if this would result in an index out of bounds exception.
     */
    public static boolean isOutOfBounds(int index, int length, int capacity) {
        return (index | length | (index + length) | (capacity - (index + length))) < 0;
    }

    /**
     * 求绝对值
     */
    public static int abs(int value) {
        return value & Integer.MAX_VALUE;
    }

    /**
     * 求平均值
     */
    public static int avg(int... values) {
        Preconditions.checkNotNull(values);
        Preconditions.checkArgument(values.length >= 1);
        return sum(values) / values.length;
    }

    /**
     * 求平均值
     */
    public static float avgFloat(float... values) {
        Preconditions.checkNotNull(values);
        Preconditions.checkArgument(values.length >= 1);
        return sumFloat(values) / values.length;
    }

    /**
     * 求平均值
     */
    public static long avgLong(long... values) {
        Preconditions.checkNotNull(values);
        Preconditions.checkArgument(values.length >= 1);
        return sumLong(values) / values.length;
    }

    /**
     * 求平均值
     */
    public static double avgDouble(double... values) {
        Preconditions.checkNotNull(values);
        Preconditions.checkArgument(values.length >= 1);
        return sumDouble(values) / values.length;
    }

    /**
     * 求总和
     */
    public static int sum(int... values) {
        return Pipeline.of(values).sum().intValue();
    }

    /**
     * 求总和
     */
    public static float sumFloat(float... values) {
        return Pipeline.of(values).sum().floatValue();
    }

    /**
     * 求总和
     */
    public static long sumLong(long... values) {
        return Pipeline.of(values).sum().longValue();
    }

    /**
     * 求总和
     */
    public static double sumDouble(double... values) {
        return Pipeline.of(values).sum();
    }

    /**
     * 格式化小数点后多少位
     *
     * @param value     要格式化的值
     * @param precision 小数点后保留位数
     * @return 格式化后的值
     */
    public static Double formatPrecision(double value, int precision) {
        return formatPrecision(value, precision, RoundingMode.HALF_UP);
    }

    /**
     * 格式化小数点后多少位
     *
     * @param value     要格式化的值
     * @param precision 小数点后保留位数
     * @return 格式化后的值
     */
    public static Double formatPrecision(double value, int precision, RoundingMode roundingMode) {
        Preconditions.checkArgument(precision >= 0);
        final StringBuilder pattern = precision > 0 ? new StringBuilder("#.") : new StringBuilder("#");
        Collects.forEach(Arrs.range(precision), new Consumer() {
            @Override
            public void accept(Integer integer) {
                pattern.append("0");
            }
        });

        NumberFormat nf = new DecimalFormat(pattern.toString());
        nf.setMaximumFractionDigits(precision);
        nf.setRoundingMode(roundingMode == null ? RoundingMode.HALF_UP : roundingMode);
        String string = nf.format(value);
        return Double.parseDouble(string);
    }

    public static int pow2Int(int pow) {
        return Numbers.toInt(Math.pow(2, pow));
    }

    public static int pow2Long(int pow) {
        return Numbers.toInt(Math.pow(2, pow));
    }

    /**
     * Returns the sum of {@code a} and {@code b} unless it would overflow or underflow in which case
     * {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively.
     *
     * @since 2.10.3
     */
    public static long saturatedAdd(long a, long b) {
        long naiveSum = a + b;
        if ((a ^ b) < 0 | (a ^ naiveSum) >= 0) {
            // If a and b have different signs or a has the same sign as the result then there was no
            // overflow, return.
            return naiveSum;
        }
        // we did over/under flow, if the sign is negative we should return MAX otherwise MIN
        return Long.MAX_VALUE + ((naiveSum >>> (Long.SIZE - 1)) ^ 1);
    }

    /**
     * Returns the difference of {@code a} and {@code b} unless it would overflow or underflow in
     * which case {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively.
     *
     * @since 2.10.3
     */
    public static long saturatedSubtract(long a, long b) {
        long naiveDifference = a - b;
        if ((a ^ b) >= 0 | (a ^ naiveDifference) >= 0) {
            // If a and b have the same signs or a has the same sign as the result then there was no
            // overflow, return.
            return naiveDifference;
        }
        // we did over/under flow
        return Long.MAX_VALUE + ((naiveDifference >>> (Long.SIZE - 1)) ^ 1);
    }

    /**
     * Returns the product of {@code a} and {@code b} unless it would overflow or underflow in which
     * case {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively.
     *
     * @since 2.10.3
     */
    public static long saturatedMultiply(long a, long b) {
        // see checkedMultiply for explanation
        int leadingZeros =
                Long.numberOfLeadingZeros(a)
                        + Long.numberOfLeadingZeros(~a)
                        + Long.numberOfLeadingZeros(b)
                        + Long.numberOfLeadingZeros(~b);
        if (leadingZeros > Long.SIZE + 1) {
            return a * b;
        }
        // the return value if we will overflow (which we calculate by overflowing a long :) )
        long limit = Long.MAX_VALUE + ((a ^ b) >>> (Long.SIZE - 1));
        if (leadingZeros < Long.SIZE | (a < 0 & b == Long.MIN_VALUE)) {
            // overflow
            return limit;
        }
        long result = a * b;
        if (a == 0 || result / a == b) {
            return result;
        }
        return limit;
    }

    static final long FLOOR_SQRT_MAX_LONG = 3037000499L;

    /**
     * Returns the {@code b} to the {@code k}th power, unless it would overflow or underflow in which
     * case {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively.
     *
     * @since 2.10.3
     */

    public static long saturatedPow(long b, int k) {
        if (k < 0) {
            throw new IllegalArgumentException(" Argument k must be >= 0");
        }
        if (b >= -2 & b <= 2) {
            switch ((int) b) {
                case 0:
                    return (k == 0) ? 1 : 0;
                case 1:
                    return 1;
                case (-1):
                    return ((k & 1) == 0) ? 1 : -1;
                case 2:
                    if (k >= Long.SIZE - 1) {
                        return Long.MAX_VALUE;
                    }
                    return 1L << k;
                case (-2):
                    if (k >= Long.SIZE) {
                        return Long.MAX_VALUE + (k & 1);
                    }
                    return ((k & 1) == 0) ? (1L << k) : (-1L << k);
                default:
                    throw new AssertionError();
            }
        }
        long accum = 1;
        // if b is negative and k is odd then the limit is MIN otherwise the limit is MAX
        long limit = Long.MAX_VALUE + ((b >>> Long.SIZE - 1) & (k & 1));
        while (true) {
            switch (k) {
                case 0:
                    return accum;
                case 1:
                    return saturatedMultiply(accum, b);
                default:
                    if ((k & 1) != 0) {
                        accum = saturatedMultiply(accum, b);
                    }
                    k >>= 1;
                    if (k > 0) {
                        if (-FLOOR_SQRT_MAX_LONG > b | b > FLOOR_SQRT_MAX_LONG) {
                            return limit;
                        }
                        b *= b;
                    }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy