Class PhiloxSupport

java.lang.Object
org.apache.commons.rng.core.source64.PhiloxSupport

final class PhiloxSupport extends Object
Utility support for the Philox family of generators.

Contains methods that use the java.lang.invoke package to call java.lang.Math functions for computing the high part of the 128-bit result of a multiply of two 64-bit longs. These methods may be supported by intrinsic calls to native operations if supported on the platform for a significant performance gain.

Note

This class is used specifically in the Philox4x64 generator which has a state update cycle which is performance dependent on the multiply of two unsigned long values. Other classes which use unsigned multiply and are not performance dependent on the method do not use this implementation (for example the LXM family of generators). This allows the multiply method to be adapted to the usage of Philox4x64 which always has the first argument as a negative constant.

Since:
1.7
  • Field Details

    • UNSIGNED_MULTIPLY_HIGH

      private static final LongBinaryOperator UNSIGNED_MULTIPLY_HIGH
      Method to compute unsigned multiply high. Uses:
      • java.lang.Math.unsignedMultiplyHigh if Java 18
      • java.lang.Math.multiplyHigh if Java 9
      • otherwise a default implementation.
  • Constructor Details

    • PhiloxSupport

      private PhiloxSupport()
      No instances.
  • Method Details

    • getMathUnsignedMultiplyHigh

      private static LongBinaryOperator getMathUnsignedMultiplyHigh()
      Gets a method to compute the high 64-bits of an unsigned 64-bit multiplication using the Math unsignedMultiplyHigh method from JDK 18.
      Returns:
      the method, or null
    • getMathMultiplyHigh

      private static LongBinaryOperator getMathMultiplyHigh()
      Gets a method to compute the high 64-bits of an unsigned 64-bit multiplication using the Math multiplyHigh method from JDK 9.
      Returns:
      the method, or null
    • getMathMethod

      static MethodHandle getMathMethod(String methodName) throws NoSuchMethodException, IllegalAccessException
      Gets the named method from the Math class.

      The look-up assumes the named method accepts two long arguments and returns a long.

      Parameters:
      methodName - Method name.
      Returns:
      the method
      Throws:
      NoSuchMethodException - if the method does not exist
      IllegalAccessException - if the method cannot be accessed
    • testUnsignedMultiplyHigh

      static boolean testUnsignedMultiplyHigh(LongBinaryOperator op)
      Test the implementation of unsigned multiply high. It is assumed the invocation of the method may raise an IllegalStateException if it cannot be invoked.
      Parameters:
      op - Method implementation.
      Returns:
      True if the method can be called to generate the expected result
    • unsignedMultiplyHigh

      static long unsignedMultiplyHigh(long value1, long value2)
      Multiply the two values as if unsigned 64-bit longs to produce the high 64-bits of the 128-bit unsigned result. The first argument is assumed to be negative.

      This method uses a MethodHandle to call Java functions added since Java 8 to the Math class:

      • java.lang.Math.unsignedMultiplyHigh if Java 18
      • java.lang.Math.multiplyHigh if Java 9
      • otherwise a default implementation.

      Warning

      For performance reasons this method assumes the first argument is negative. This allows some operations to be dropped if running on Java 9 to 17.

      Parameters:
      value1 - the first value (must be negative)
      value2 - the second value
      Returns:
      the high 64-bits of the 128-bit result