IntMath.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.statistics.descriptive;

  18. import java.math.BigDecimal;
  19. import java.math.BigInteger;
  20. import org.apache.commons.numbers.core.DD;

  21. /**
  22.  * Support class for integer math.
  23.  *
  24.  * @since 1.1
  25.  */
  26. final class IntMath {
  27.     /** Mask for the lower 32-bits of a long. */
  28.     private static final long MASK32 = 0xffff_ffffL;
  29.     /** Mask for the lower 52-bits of a long. */
  30.     private static final long MASK52 = 0xf_ffff_ffff_ffffL;
  31.     /** Bias offset for the exponent of a double. */
  32.     private static final int EXP_BIAS = 1023;
  33.     /** Shift for the exponent of a double. */
  34.     private static final int EXP_SHIFT = 52;
  35.     /** 0.5. */
  36.     private static final double HALF = 0.5;
  37.     /** 2^53. */
  38.     private static final long TWO_POW_53 = 1L << 53;

  39.     /** No instances. */
  40.     private IntMath() {}

  41.     /**
  42.      * Square the values as if an unsigned 64-bit long to produce the high 64-bits
  43.      * of the 128-bit unsigned result.
  44.      *a
  45.      * <p>This method computes the equivalent of:
  46.      * <pre>{@code
  47.      * Math.multiplyHigh(x, x)
  48.      * Math.unsignedMultiplyHigh(x, x) - (((x >> 63) & x) << 1)
  49.      * }</pre>
  50.      *
  51.      * <p>Note: The method {@code Math.multiplyHigh} was added in JDK 9
  52.      * and should be used as above when the source code targets Java 11
  53.      * to exploit the intrinsic method.
  54.      *
  55.      * <p>Note: The method uses the unsigned multiplication. When the input is negative
  56.      * it can be adjusted to the signed result by subtracting the argument twice from the
  57.      * result.
  58.      *
  59.      * @param x Value
  60.      * @return the high 64-bits of the 128-bit result
  61.      */
  62.     static long squareHigh(long x) {
  63.         // Computation is based on the following observation about the upper (a and x)
  64.         // and lower (b and y) bits of unsigned big-endian integers:
  65.         //   ab * xy
  66.         // =  b *  y
  67.         // +  b * x0
  68.         // + a0 *  y
  69.         // + a0 * x0
  70.         // = b * y
  71.         // + b * x * 2^32
  72.         // + a * y * 2^32
  73.         // + a * x * 2^64
  74.         //
  75.         // Summation using a character for each byte:
  76.         //
  77.         //             byby byby
  78.         // +      bxbx bxbx 0000
  79.         // +      ayay ayay 0000
  80.         // + axax axax 0000 0000
  81.         //
  82.         // The summation can be rearranged to ensure no overflow given
  83.         // that the result of two unsigned 32-bit integers multiplied together
  84.         // plus two full 32-bit integers cannot overflow 64 bits:
  85.         // > long x = (1L << 32) - 1
  86.         // > x * x + x + x == -1 (all bits set, no overflow)
  87.         //
  88.         // The carry is a composed intermediate which will never overflow:
  89.         //
  90.         //             byby byby
  91.         // +           bxbx 0000
  92.         // +      ayay ayay 0000
  93.         //
  94.         // +      bxbx 0000 0000
  95.         // + axax axax 0000 0000

  96.         final long a = x >>> 32;
  97.         final long b = x & MASK32;

  98.         final long aa = a * a;
  99.         final long ab = a * b;
  100.         final long bb = b * b;

  101.         // Cannot overflow
  102.         final long carry = (bb >>> 32) +
  103.                            (ab & MASK32) +
  104.                             ab;
  105.         // Note:
  106.         // low = (carry << 32) | (bb & MASK32)
  107.         // Benchmarking shows outputting low to a long[] output argument
  108.         // has no benefit over computing 'low = value * value' separately.

  109.         final long hi = (ab >>> 32) + (carry >>> 32) + aa;
  110.         // Adjust to the signed result:
  111.         // if x < 0:
  112.         //    hi - 2 * x
  113.         return hi - (((x >> 63) & x) << 1);
  114.     }

  115.     /**
  116.      * Multiply the two values as if unsigned 64-bit longs to produce the high 64-bits
  117.      * of the 128-bit unsigned result.
  118.      *
  119.      * <p>This method computes the equivalent of:
  120.      * <pre>{@code
  121.      * Math.multiplyHigh(a, b) + ((a >> 63) & b) + ((b >> 63) & a)
  122.      * }</pre>
  123.      *
  124.      * <p>Note: The method {@code Math.multiplyHigh} was added in JDK 9
  125.      * and should be used as above when the source code targets Java 11
  126.      * to exploit the intrinsic method.
  127.      *
  128.      * <p>Note: The method {@code Math.unsignedMultiplyHigh} was added in JDK 18
  129.      * and should be used when the source code target allows.
  130.      *
  131.      * <p>Taken from {@code o.a.c.rng.core.source64.LXMSupport}.
  132.      *
  133.      * @param value1 the first value
  134.      * @param value2 the second value
  135.      * @return the high 64-bits of the 128-bit result
  136.      */
  137.     static long unsignedMultiplyHigh(long value1, long value2) {
  138.         // Computation is based on the following observation about the upper (a and x)
  139.         // and lower (b and y) bits of unsigned big-endian integers:
  140.         //   ab * xy
  141.         // =  b *  y
  142.         // +  b * x0
  143.         // + a0 *  y
  144.         // + a0 * x0
  145.         // = b * y
  146.         // + b * x * 2^32
  147.         // + a * y * 2^32
  148.         // + a * x * 2^64
  149.         //
  150.         // Summation using a character for each byte:
  151.         //
  152.         //             byby byby
  153.         // +      bxbx bxbx 0000
  154.         // +      ayay ayay 0000
  155.         // + axax axax 0000 0000
  156.         //
  157.         // The summation can be rearranged to ensure no overflow given
  158.         // that the result of two unsigned 32-bit integers multiplied together
  159.         // plus two full 32-bit integers cannot overflow 64 bits:
  160.         // > long x = (1L << 32) - 1
  161.         // > x * x + x + x == -1 (all bits set, no overflow)
  162.         //
  163.         // The carry is a composed intermediate which will never overflow:
  164.         //
  165.         //             byby byby
  166.         // +           bxbx 0000
  167.         // +      ayay ayay 0000
  168.         //
  169.         // +      bxbx 0000 0000
  170.         // + axax axax 0000 0000

  171.         final long a = value1 >>> 32;
  172.         final long b = value1 & MASK32;
  173.         final long x = value2 >>> 32;
  174.         final long y = value2 & MASK32;

  175.         final long by = b * y;
  176.         final long bx = b * x;
  177.         final long ay = a * y;
  178.         final long ax = a * x;

  179.         // Cannot overflow
  180.         final long carry = (by >>> 32) +
  181.                            (bx & MASK32) +
  182.                             ay;
  183.         // Note:
  184.         // low = (carry << 32) | (by & INT_TO_UNSIGNED_BYTE_MASK)
  185.         // Benchmarking shows outputting low to a long[] output argument
  186.         // has no benefit over computing 'low = value1 * value2' separately.

  187.         return (bx >>> 32) + (carry >>> 32) + ax;
  188.     }

  189.     /**
  190.      * Multiply the arguments as if unsigned integers to a {@code double} result.
  191.      *
  192.      * @param x Value.
  193.      * @param y Value.
  194.      * @return the double
  195.      */
  196.     static double unsignedMultiplyToDouble(long x, long y) {
  197.         final long lo = x * y;
  198.         // Fast case: check the arguments cannot overflow a long.
  199.         // This is true if neither has the upper 33-bits set.
  200.         if (((x | y) >>> 31) == 0) {
  201.             // Implicit conversion to a double.
  202.             return lo;
  203.         }
  204.         return uint128ToDouble(unsignedMultiplyHigh(x, y), lo);
  205.     }

  206.     /**
  207.      * Convert an unsigned 128-bit integer to a {@code double}.
  208.      *
  209.      * @param hi High 64-bits.
  210.      * @param lo Low 64-bits.
  211.      * @return the double
  212.      */
  213.     static double uint128ToDouble(long hi, long lo) {
  214.         // Require the representation:
  215.         // 2^exp * mantissa / 2^53
  216.         // The mantissa has an implied leading 1-bit.

  217.         // We have the mantissa final bit as xxx0 or xxx1.
  218.         // To perform correct rounding we maintain the 54-th bit (a) and
  219.         // a check bit (b) of remaining bits.
  220.         // Cases:
  221.         // xxx0 00 - round-down              [1]
  222.         // xxx0 0b - round-down              [1]
  223.         // xxx0 a0 - half-even, round-down   [4]
  224.         // xxx0 ab - round-up                [2]
  225.         // xxx1 00 - round-down              [1]
  226.         // xxx1 0b - round-down              [1]
  227.         // xxx1 a0 - half-even, round-up     [3]
  228.         // xxx1 ab - round-up                [2]
  229.         // [1] If the 54-th bit is 0 always round-down.
  230.         // [2] Otherwise round-up if the check bit is set or
  231.         // [3] the final bit is odd (half-even rounding up).
  232.         // [4] half-even rounding down.

  233.         if (hi == 0) {
  234.             // If lo is a 63-bit result then we are done
  235.             if (lo >= 0) {
  236.                 return lo;
  237.             }
  238.             // Create a 63-bit number with a sticky bit for rounding, rescale the result
  239.             return 2 * (double) ((lo >>> 1) | (lo & 0x1));
  240.         }

  241.         // Initially we create the most significant 64-bits.
  242.         final int shift = Long.numberOfLeadingZeros(hi);
  243.         // Shift the high bits and add trailing low bits.
  244.         // The mask is for the bits from low that are *not* used.
  245.         // Flipping the mask obtains the bits we concatenate
  246.         // after shifting (64 - shift).
  247.         final long maskLow = -1L >>> shift;
  248.         long bits64 = (hi << shift) | ((lo & ~maskLow) >>> -shift);
  249.         // exponent for 2^exp is the index of the highest bit in the 128 bit integer
  250.         final int exp = 127 - shift;
  251.         // Some of the low bits are lost. If non-zero set
  252.         // a sticky bit for rounding.
  253.         bits64 |= (lo & maskLow) == 0 ? 0 : 1;

  254.         // We have a 64-bit unsigned fraction magnitude and an exponent.
  255.         // This must be converted to a IEEE double by mapping the fraction to a base of 2^53.

  256.         // Create the 53-bit mantissa without the implicit 1-bit
  257.         long bits = (bits64 >>> 11) & MASK52;
  258.         // Extract 54-th bit and a sticky bit
  259.         final long a = (bits64 >>> 10) & 0x1;
  260.         final long b = (bits64 << 54) == 0 ? 0 : 1;
  261.         // Perform half-even rounding.
  262.         bits += a & (b | (bits & 0x1));

  263.         // Add the exponent.
  264.         // No worry about overflow to the sign bit as the max exponent is 127.
  265.         bits += (long) (exp + EXP_BIAS) << EXP_SHIFT;

  266.         return Double.longBitsToDouble(bits);
  267.     }

  268.     /**
  269.      * Return the whole number that is nearest to the {@code double} argument {@code x}
  270.      * as an {@code int}, with ties rounding towards positive infinity.
  271.      *
  272.      * <p>This will raise an {@link ArithmeticException} if the closest
  273.      * integer result is not within the range {@code [-2^31, 2^31)},
  274.      * i.e. it overflows an {@code int}; or the argument {@code x}
  275.      * is not finite.
  276.      *
  277.      * <p>Note: This method is equivalent to:
  278.      * <pre>
  279.      * Math.toIntExact(Math.round(x))
  280.      * </pre>
  281.      *
  282.      * <p>The behaviour has been re-implemented for consistent error handling
  283.      * for {@code int}, {@code long} and {@code BigInteger} types.
  284.      *
  285.      * @param x Value.
  286.      * @return rounded value
  287.      * @throws ArithmeticException if the {@code result} overflows an {@code int},
  288.      * or {@code x} is not finite
  289.      * @see Math#round(double)
  290.      * @see Math#toIntExact(long)
  291.      */
  292.     static int toIntExact(double x) {
  293.         final double r = roundToInteger(x);
  294.         if (r >= -0x1.0p31 && r < 0x1.0p31) {
  295.             return (int) r;
  296.         }
  297.         throw new ArithmeticException("integer overflow: " + x);
  298.     }

  299.     /**
  300.      * Return the whole number that is nearest to the {@code double} argument {@code x}
  301.      * as an {@code long}, with ties rounding towards positive infinity.
  302.      *
  303.      * <p>This will raise an {@link ArithmeticException} if the closest
  304.      * integer result is not within the range {@code [-2^63, 2^63)},
  305.      * i.e. it overflows a {@code long}; or the argument {@code x}
  306.      * is not finite.
  307.      *
  308.      * @param x Value.
  309.      * @return rounded value
  310.      * @throws ArithmeticException if the {@code result} overflows a {@code long},
  311.      * or {@code x} is not finite
  312.      */
  313.     static long toLongExact(double x) {
  314.         final double r = roundToInteger(x);
  315.         if (r >= -0x1.0p63 && r < 0x1.0p63) {
  316.             return (long) r;
  317.         }
  318.         throw new ArithmeticException("long integer overflow: " + x);
  319.     }

  320.     /**
  321.      * Return the whole number that is nearest to the {@code double} argument {@code x}
  322.      * as an {@code int}, with ties rounding towards positive infinity.
  323.      *
  324.      * <p>This will raise an {@link ArithmeticException} if the argument {@code x}
  325.      * is not finite.
  326.      *
  327.      * @param x Value.
  328.      * @return rounded value
  329.      * @throws ArithmeticException if {@code x} is not finite
  330.      */
  331.     static BigInteger toBigIntegerExact(double x) {
  332.         if (!Double.isFinite(x)) {
  333.             throw new ArithmeticException("BigInteger overflow: " + x);
  334.         }
  335.         final double r = roundToInteger(x);
  336.         if (r >= -0x1.0p63 && r < 0x1.0p63) {
  337.             // Representable as a long
  338.             return BigInteger.valueOf((long) r);
  339.         }
  340.         // Large result
  341.         return new BigDecimal(r).toBigInteger();
  342.     }

  343.     /**
  344.      * Get the whole number that is the nearest to x, with ties rounding towards positive infinity.
  345.      *
  346.      * <p>This method is intended to perform the equivalent of
  347.      * {@link Math#round(double)} without converting to a {@code long} primitive type.
  348.      * This allows the domain of the result to be checked against the range {@code [-2^63, 2^63)}.
  349.      *
  350.      * <p>Note: Adapted from {@code o.a.c.math4.AccurateMath.rint} and
  351.      * modified to perform rounding towards positive infinity.
  352.      *
  353.      * @param x Number from which nearest whole number is requested.
  354.      * @return a double number r such that r is an integer {@code r - 0.5 <= x < r + 0.5}
  355.      */
  356.     private static double roundToInteger(double x) {
  357.         final double y = Math.floor(x);
  358.         final double d = x - y;
  359.         if (d >= HALF) {
  360.             // Here we do not preserve the sign of the operand in the case
  361.             // of -0.5 < x <= -0.0 since the rounded result is required as an integer.
  362.             // if y == -1.0:
  363.             //    return -0.0
  364.             return y + 1.0;
  365.         }
  366.         return y;
  367.     }

  368.     /**
  369.      * Divide value {@code x} by the count {@code n}.
  370.      *
  371.      * @param x Value.
  372.      * @param n Count.
  373.      * @return the quotient
  374.      */
  375.     static double divide(Int128 x, long n) {
  376.         final DD a = x.toDD();
  377.         if (n < TWO_POW_53) {
  378.             // n is a representable double
  379.             return a.divide(n).doubleValue();
  380.         }
  381.         // Extended precision divide when n > 2^53
  382.         return a.divide(DD.of(n)).doubleValue();
  383.     }
  384. }