Correct longAsInt output in the stress test application

RNG-171 changed the cached int source to output a long as two ints using
the low 32-bits, then high 32-bits.

Updated the RngDataOutput to support HiLo or LoHi. Added tests for each
implementation.

Dropped high-bits and low-bits command options. Added source64 option
with enum for high, low, high-Low, low-high, long, int. The default for
stress testing matches the caching implementation.

Update the test documentation to reflect the changes.
diff --git a/commons-rng-examples/examples-stress/endianness.md b/commons-rng-examples/examples-stress/endianness.md
index 56567f8..95bc9b9 100644
--- a/commons-rng-examples/examples-stress/endianness.md
+++ b/commons-rng-examples/examples-stress/endianness.md
@@ -59,12 +59,12 @@
 contains a simple command to output data from a random generator. To output data in both text
 and binary format use the following commands:
 
-        java -jar target/examples-stress.jar output SPLIT_MIX_64 -s 1 -n 100000 \
+        java -jar target/examples-stress.jar output KISS -s 1 -n 2048000 \
                 -f DIEHARDER -o test.dh
-        java -jar target/examples-stress.jar output SPLIT_MIX_64 -s 1 -n 100000 \
-                -f BINARY -o test.big -b big_endian
-        java -jar target/examples-stress.jar output SPLIT_MIX_64 -s 1 -n 100000 \
-                -f BINARY -o test.little -b little_endian
+        java -jar target/examples-stress.jar output KISS -s 1 -n 1000 \
+                -f BINARY -o test.big -b big_endian --buffer-size 8192
+        java -jar target/examples-stress.jar output KISS -s 1 -n 1000 \
+                -f BINARY -o test.little -b little_endian --buffer-size 8192
 
 This should produce the following output files:
 
@@ -74,6 +74,8 @@
 | test.big | Binary file using the big-endian format |
 | test.little | Binary file using the little-endian format |
 
+Note that the `-n` parameter is the count of numbers in text output but the count of buffers in binary output. The example above has 2048 4-byte integers per 8192 buffer. The `-n` parameter has been adjusted so the output numbers are the same.
+
 The data can then be used to run a test within **Dieharder**:
 
         dieharder -g 202 -d 0 -f test.dh
@@ -89,10 +91,10 @@
 In the following example the stress test application directly writes to `stdout` which is then
 piped to the `dieharder` application which reads using `stdin` (`-g 200` option):
 
-        java -jar target/examples-stress.jar output SPLIT_MIX_64 -s 1 -n 20000000 \
+        java -jar target/examples-stress.jar output KISS -s 1 -n 20000000 \
                 -f DIEHARDER -o test.dh
         dieharder -g 202 -d 0 -f test.dh
-        java -jar target/examples-stress.jar output SPLIT_MIX_64 -s 1 -n 20000000 \
+        java -jar target/examples-stress.jar output KISS -s 1 -n 10000 \
                 -f BINARY -b little_endian | dieharder -g 200 -d 0
 
 If the results are not the same then the second command can be repeated with `-b big_endian`.
@@ -150,7 +152,7 @@
         01011100 10001111 11110001 11000001  1552937409  1552937409
         10110000 01110101 10010011 00011100  2960495388 -1334471908
 
-The `stdin2testu01` has been written to output the same format when using the `raw32` mode.
+The `stdin2testu01` has been written to output in the same format when using the `raw32` mode.
 If the data has been correctly read the `bridge.data` and `bridge.out` should match.
 If the endianess is incorrect then the data sent by the Java application will not match the
 data read by the sub-process. For example to swap the endianness use the `-b` option:
@@ -215,7 +217,7 @@
 The only difference should be the the header and footer added by the `stress` command
 to the results file. If the endianness is incorrect for the `output` command then the number
 data will not match. Note that the `output` command by default uses big endian for consistency
-across all platforms.
+across all platforms; the `stress` command uses the native byte order of the platform.
 
 An equivalent 64-bit output would use the `--raw64` option for each command:
 
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
index f32e71c..70a2a04 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
@@ -131,8 +131,8 @@
             // Open the stdin of the process and write to a custom data sink.
             // Note: The 'bridge' command only supports 32-bit data in order to
             // demonstrate passing suitable data for TestU01 BigCrush.
-            final boolean raw64 = false;
-            try (RngDataOutput sink = RNGUtils.createDataOutput(rng, raw64,
+            final Source64Mode source64 = null;
+            try (RngDataOutput sink = RNGUtils.createDataOutput(rng, source64,
                     testingProcess.getOutputStream(), buffer.capacity() * 4, byteOrder)) {
                 sink.write(rng);
             }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
index 6b0765a..bb2a7bc 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
@@ -126,25 +126,22 @@
             description = {"Reverse the bits in the data (default: ${DEFAULT-VALUE})."})
     private boolean reverseBits;
 
-    /** Flag to use the upper 32-bits from the 64-bit long output. */
-    @Option(names = {"--high-bits"},
-            description = {"Use the upper 32-bits from the 64-bit long output.",
-                           "Takes precedent over --low-bits."})
-    private boolean longHighBits;
-
-    /** Flag to use the lower 32-bits from the 64-bit long output. */
-    @Option(names = {"--low-bits"},
-            description = {"Use the lower 32-bits from the 64-bit long output."})
-    private boolean longLowBits;
-
     /** Flag to use 64-bit long output. */
     @Option(names = {"--raw64"},
             description = {"Use 64-bit output (default is 32-bit).",
                            "This is ignored if not a native 64-bit generator.",
-                           "In 32-bit mode the output uses the upper then lower bits of 64-bit " +
-                           "generators sequentially."})
+                           "Set to true sets the source64 mode to LONG."})
     private boolean raw64;
 
+    /** Output mode for 64-bit long output. */
+    @Option(names = {"--source64"},
+            description = {"Output mode for 64-bit generators (default: ${DEFAULT-VALUE}).",
+                           "This is ignored if not a native 64-bit generator.",
+                           "In 32-bit mode the output uses a combination of upper and " +
+                           "lower bits of the 64-bit value.",
+                           "Valid values: ${COMPLETION-CANDIDATES}."})
+    private Source64Mode source64 = RNGUtils.getSource64Default();
+
     /**
      * The output mode for existing files.
      */
@@ -166,12 +163,20 @@
         final Object objectSeed = createSeed();
         UniformRandomProvider rng = createRNG(objectSeed);
 
+        // raw64 flag overrides the source64 mode
+        if (raw64) {
+            source64 = Source64Mode.LONG;
+        }
+        if (source64 == Source64Mode.LONG && !(rng instanceof RandomLongSource)) {
+            throw new ApplicationException("Not a 64-bit RNG: " + rng);
+        }
+
         // Upper or lower bits from 64-bit generators must be created first.
-        // This will throw if not a 64-bit generator.
-        if (longHighBits) {
-            rng = RNGUtils.createLongUpperBitsIntProvider(rng);
-        } else if (longLowBits) {
-            rng = RNGUtils.createLongLowerBitsIntProvider(rng);
+        // Note this does not test source64 != Source64Mode.LONG as the full long
+        // output split into hi-lo or lo-hi is supported by the RngDataOutput.
+        if (rng instanceof RandomLongSource &&
+            (source64 == Source64Mode.HI || source64 == Source64Mode.LO || source64 == Source64Mode.INT)) {
+            rng = RNGUtils.createIntProvider((UniformRandomProvider & RandomLongSource) rng, source64);
         }
         if (reverseBits) {
             rng = RNGUtils.createReverseBitsProvider(rng);
@@ -305,9 +310,9 @@
      */
     private UniformRandomProvider toOutputFormat(UniformRandomProvider rng) {
         UniformRandomProvider convertedRng = rng;
-        if (rng instanceof RandomLongSource && !raw64) {
+        if (rng instanceof RandomLongSource && source64 != Source64Mode.LONG) {
             // Convert to 32-bit generator
-            convertedRng = RNGUtils.createIntProvider(rng);
+            convertedRng = RNGUtils.createIntProvider((UniformRandomProvider & RandomLongSource) rng, source64);
         }
         if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
             convertedRng = RNGUtils.createReverseBytesProvider(convertedRng);
@@ -421,7 +426,7 @@
         // If count is not positive use max value.
         // This is effectively unlimited: program must be killed.
         final long limit = (count < 1) ? Long.MAX_VALUE : count;
-        try (RngDataOutput data = RNGUtils.createDataOutput(rng, raw64, out, bufferSize, byteOrder)) {
+        try (RngDataOutput data = RNGUtils.createDataOutput(rng, source64, out, bufferSize, byteOrder)) {
             for (long c = 0; c < limit; c++) {
                 data.write(rng);
             }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RNGUtils.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RNGUtils.java
index 29c09a5..4d799c9 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RNGUtils.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RNGUtils.java
@@ -33,7 +33,7 @@
 final class RNGUtils {
     /** Name prefix for bit-reversed RNGs. */
     private static final String BYTE_REVERSED = "Byte-reversed ";
-    /** Name prefix for byte-reversed RNGs. */
+    /** Name prefix for bit-reversed RNGs. */
     private static final String BIT_REVERSED = "Bit-reversed ";
     /** Name prefix for hashcode mixed RNGs. */
     private static final String HASH_CODE = "HashCode ^ ";
@@ -41,15 +41,26 @@
     private static final String TLR_MIXED = "ThreadLocalRandom ^ ";
     /** Name of xor operator for xor mixed RNGs. */
     private static final String XOR = " ^ ";
+    /** Message for an unrecognised source64 mode. */
+    private static final String UNRECOGNISED_SOURCE_64_MODE = "Unrecognised source64 mode: ";
     /** Message for an unrecognised native output type. */
     private static final String UNRECOGNISED_NATIVE_TYPE = "Unrecognised native output type: ";
-    /** Message when not a RandomLongSource. */
-    private static final String NOT_LONG_SOURCE = "Not a 64-bit long generator: ";
+    /** The source64 mode for the default LongProvider caching implementation. */
+    private static final Source64Mode SOURCE_64_DEFAULT = Source64Mode.LO_HI;
 
     /** No public construction. */
     private RNGUtils() {}
 
     /**
+     * Gets the source64 mode for the default caching implementation in {@link LongProvider}.
+     *
+     * @return the source64 default mode
+     */
+    static Source64Mode getSource64Default() {
+        return SOURCE_64_DEFAULT;
+    }
+
+    /**
      * Wrap the random generator with a new instance that will reverse the byte order of
      * the native type. The input must be either a {@link RandomIntSource} or
      * {@link RandomLongSource}.
@@ -132,6 +143,35 @@
     }
 
     /**
+     * Wrap the {@link RandomLongSource} with an {@link IntProvider} that will use the
+     * specified part of {@link RandomLongSource#next()} to create the int value.
+     *
+     * @param <R> The type of the generator.
+     * @param rng The random generator.
+     * @param mode the mode
+     * @return the int random generator.
+     * @throws ApplicationException If the input source native type is not 64-bit.
+     */
+    static <R extends RandomLongSource & UniformRandomProvider>
+            UniformRandomProvider createIntProvider(final R rng, Source64Mode mode) {
+        switch (mode) {
+        case INT:
+            return createIntProvider(rng);
+        case LO_HI:
+            return createLongLowerUpperBitsIntProvider(rng);
+        case HI_LO:
+            return createLongUpperLowerBitsIntProvider(rng);
+        case HI:
+            return createLongUpperBitsIntProvider(rng);
+        case LO:
+            return createLongLowerBitsIntProvider(rng);
+        case LONG:
+        default:
+            throw new IllegalArgumentException("Unsupported mode " + mode);
+        }
+    }
+
+    /**
      * Wrap the random generator with an {@link IntProvider} that will use
      * {@link UniformRandomProvider#nextInt()}.
      * An input {@link RandomIntSource} is returned unmodified.
@@ -139,7 +179,7 @@
      * @param rng The random generator.
      * @return the int random generator.
      */
-    static UniformRandomProvider createIntProvider(final UniformRandomProvider rng) {
+    private static UniformRandomProvider createIntProvider(final UniformRandomProvider rng) {
         if (!(rng instanceof RandomIntSource)) {
             return new IntProvider() {
                 @Override
@@ -157,6 +197,78 @@
     }
 
     /**
+     * Wrap the random generator with an {@link IntProvider} that will use the lower then upper
+     * 32-bits from {@link UniformRandomProvider#nextLong()}.
+     * An input {@link RandomIntSource} is returned unmodified.
+     *
+     * @param rng The random generator.
+     * @return the int random generator.
+     */
+    private static UniformRandomProvider createLongLowerUpperBitsIntProvider(final RandomLongSource rng) {
+        return new IntProvider() {
+            private long source = -1;
+
+            @Override
+            public int next() {
+                long next = source;
+                if (next < 0) {
+                    // refill
+                    next = rng.next();
+                    // store hi
+                    source = next >>> 32;
+                    // extract low
+                    return (int) next;
+                }
+                final int v = (int) next;
+                // reset
+                source = -1;
+                return v;
+            }
+
+            @Override
+            public String toString() {
+                return "Long lower-upper bits " + rng.toString();
+            }
+        };
+    }
+
+    /**
+     * Wrap the random generator with an {@link IntProvider} that will use the lower then upper
+     * 32-bits from {@link UniformRandomProvider#nextLong()}.
+     * An input {@link RandomIntSource} is returned unmodified.
+     *
+     * @param rng The random generator.
+     * @return the int random generator.
+     */
+    private static UniformRandomProvider createLongUpperLowerBitsIntProvider(final RandomLongSource rng) {
+        return new IntProvider() {
+            private long source = -1;
+
+            @Override
+            public int next() {
+                long next = source;
+                if (next < 0) {
+                    // refill
+                    next = rng.next();
+                    // store low
+                    source = next & 0xffff_ffffL;
+                    // extract hi
+                    return (int) (next >>> 32);
+                }
+                final int v = (int) next;
+                // reset
+                source = -1;
+                return v;
+            }
+
+            @Override
+            public String toString() {
+                return "Long upper-lower bits " + rng.toString();
+            }
+        };
+    }
+
+    /**
      * Wrap the random generator with an {@link IntProvider} that will use the upper
      * 32-bits of the {@code long} from {@link UniformRandomProvider#nextLong()}.
      * The input must be a {@link RandomLongSource}.
@@ -165,21 +277,18 @@
      * @return the upper bits random generator.
      * @throws ApplicationException If the input source native type is not 64-bit.
      */
-    static UniformRandomProvider createLongUpperBitsIntProvider(final UniformRandomProvider rng) {
-        if (rng instanceof RandomLongSource) {
-            return new IntProvider() {
-                @Override
-                public int next() {
-                    return (int) (rng.nextLong() >>> 32);
-                }
+    private static UniformRandomProvider createLongUpperBitsIntProvider(final RandomLongSource rng) {
+        return new IntProvider() {
+            @Override
+            public int next() {
+                return (int) (rng.next() >>> 32);
+            }
 
-                @Override
-                public String toString() {
-                    return "Long upper-bits " + rng.toString();
-                }
-            };
-        }
-        throw new ApplicationException(NOT_LONG_SOURCE + rng);
+            @Override
+            public String toString() {
+                return "Long upper-bits " + rng.toString();
+            }
+        };
     }
 
     /**
@@ -191,21 +300,18 @@
      * @return the lower bits random generator.
      * @throws ApplicationException If the input source native type is not 64-bit.
      */
-    static UniformRandomProvider createLongLowerBitsIntProvider(final UniformRandomProvider rng) {
-        if (rng instanceof RandomLongSource) {
-            return new IntProvider() {
-                @Override
-                public int next() {
-                    return (int) rng.nextLong();
-                }
+    private static UniformRandomProvider createLongLowerBitsIntProvider(final RandomLongSource rng) {
+        return new IntProvider() {
+            @Override
+            public int next() {
+                return (int) rng.next();
+            }
 
-                @Override
-                public String toString() {
-                    return "Long lower-bits " + rng.toString();
-                }
-            };
-        }
-        throw new ApplicationException(NOT_LONG_SOURCE + rng);
+            @Override
+            public String toString() {
+                return "Long lower-bits " + rng.toString();
+            }
+        };
     }
 
     /**
@@ -360,32 +466,60 @@
      *
      * <p>If the RNG is a {@link RandomLongSource} then the byte output can be 32-bit or 64-bit.
      * If 32-bit then the 64-bit output will be written as if 2 {@code int} values were generated
-     * sequentially from the upper then lower 32-bits of the {@code long}. This setting is
-     * significant depending on the byte order. If using the Java standard big-endian
-     * representation the flag has no effect and the output will be the same. If using little
-     * endian the output bytes will be written as:</p>
+     * sequentially from the {@code long} (order depends on the source64 mode). This setting is
+     * significant depending on the byte order. For example for a high-low source64 mode and
+     * using the Java standard big-endian representation the output is the same as the raw 64-bit
+     * output. If using little endian the output bytes will be written as:</p>
      *
      * <pre>
      * 76543210  ->  4567  0123
      * </pre>
      *
+     * <h2>Note</h2>
+     *
+     * <p>The output from an implementation of RandomLongSource from the RNG core package
+     * may output the long bits as integers: in high-low order; in low-high order; using
+     * only the low bits; using only the high bits; or other combinations. This method
+     * allows testing the long output as if it were two int outputs, i.e. using the full
+     * bit output of a long provider with a stress test application that targets 32-bit
+     * random values (e.g. Test U01).
+     *
+     * <p>The results of stress testing can be used to determine if the provider
+     * implementation can use the upper, lower or both parts of the long output for int
+     * generation. In the case of the combined upper-lower output it is not expected that
+     * the order low-high or high-low is important given the stress test will consume
+     * thousands of numbers per test. The default 32-bit mode for a 64-bit source is high-low
+     * for backwards compatibility.
+     *
      * @param rng The random generator.
-     * @param raw64 Set to true for 64-bit byte output.
+     * @param source64 The output mode for a 64-bit source
      * @param out Output stream.
      * @param byteSize Number of bytes values to write.
      * @param byteOrder Byte order.
      * @return the data output
-     * @throws ApplicationException If the input source native type is not recognised.
+     * @throws ApplicationException If the input source native type is not recognised; or if
+     * the mode for a RandomLongSource is not one of: raw; hi-lo; or lo-hi.
      */
-    static RngDataOutput createDataOutput(final UniformRandomProvider rng, boolean raw64,
+    static RngDataOutput createDataOutput(final UniformRandomProvider rng, Source64Mode source64,
         OutputStream out, int byteSize, ByteOrder byteOrder) {
         if (rng instanceof RandomIntSource) {
             return RngDataOutput.ofInt(out, byteSize / 4, byteOrder);
         }
         if (rng instanceof RandomLongSource) {
-            return raw64 ?
-                RngDataOutput.ofLong(out, byteSize / 8, byteOrder) :
-                RngDataOutput.ofLongAsInt(out, byteSize / 8, byteOrder);
+            switch (source64) {
+            case HI_LO:
+                return RngDataOutput.ofLongAsHLInt(out, byteSize / 8, byteOrder);
+            case LO_HI:
+                return RngDataOutput.ofLongAsLHInt(out, byteSize / 8, byteOrder);
+            case LONG:
+                return RngDataOutput.ofLong(out, byteSize / 8, byteOrder);
+            // Note other options should have already been converted to an IntProvider
+            case INT:
+            case LO:
+            case HI:
+            default:
+                throw new ApplicationException(UNRECOGNISED_SOURCE_64_MODE + source64);
+            }
         }
         throw new ApplicationException(UNRECOGNISED_NATIVE_TYPE + rng);
     }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RngDataOutput.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RngDataOutput.java
index 90972d6..5abeccf 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RngDataOutput.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/RngDataOutput.java
@@ -54,6 +54,11 @@
  * {@link java.io.BufferedOutputStream#write(int) BufferedOutputStream#write(int)} that
  * occur for each {@code int} value that is written to
  * {@link java.io.DataOutputStream#writeInt(int) DataOutputStream#writeInt(int)}.</p>
+ *
+ * <p>This class has adaptors to write the long output from a RNG to two int values.
+ * To match the caching implementation in the the core LongProvider class this is tested
+ * to output int values in the same order as an instance of the LongProvider. Currently
+ * this outputs in order: low 32-bits, high 32-bits.
  */
 abstract class RngDataOutput implements Closeable {
     /** The data buffer. */
@@ -155,7 +160,8 @@
     }
 
     /**
-     * Write {@code long} data as two little-endian {@code int} values.
+     * Write {@code long} data as two little-endian {@code int} values, high 32-bits then
+     * low 32-bits.
      * <pre>
      * 76543210  ->  4567  0123
      * </pre>
@@ -180,7 +186,39 @@
         @Override
         public void fillBuffer(UniformRandomProvider rng) {
             for (int i = 0; i < buffer.length; i += 8) {
-                writeLongAsIntLE(i, rng.nextLong());
+                writeLongAsHighLowIntLE(i, rng.nextLong());
+            }
+        }
+    }
+
+    /**
+     * Write {@code long} data as two big-endian {@code int} values, low 32-bits then
+     * high 32-bits.
+     * <pre>
+     * 76543210  ->  3210  7654
+     * </pre>
+     *
+     * <p>This is a specialisation that allows the Java big-endian representation to be split
+     * into two big-endian values in the original order of lower then upper bits. In
+     * comparison the {@link BLongRngDataOutput} will output the same data as:
+     *
+     * <pre>
+     * 76543210  ->  7654  3210
+     * </pre>
+     */
+    private static class BLongAsLoHiIntRngDataOutput extends RngDataOutput {
+        /**
+         * @param out Output stream.
+         * @param size Buffer size.
+         */
+        BLongAsLoHiIntRngDataOutput(OutputStream out, int size) {
+            super(out, size);
+        }
+
+        @Override
+        public void fillBuffer(UniformRandomProvider rng) {
+            for (int i = 0; i < buffer.length; i += 8) {
+                writeLongAsLowHighIntBE(i, rng.nextLong());
             }
         }
     }
@@ -258,7 +296,7 @@
     }
 
     /**
-     * Writes an {@code long} to the buffer as eight bytes, low byte first (big-endian).
+     * Writes an {@code long} to the buffer as eight bytes, low byte first (little-endian).
      *
      * @param index the index to start writing.
      * @param value an {@code long} to be written.
@@ -276,22 +314,50 @@
 
     /**
      * Writes an {@code long} to the buffer as two integers of four bytes, each
-     * low byte first (big-endian).
+     * low byte first (little-endian). The long is written as the high 32-bits,
+     * then the low 32-bits.
+     *
+     * <p>Note: A LowHigh little-endian output is the same as {@link #writeLongLE(int, long)}.
      *
      * @param index the index to start writing.
      * @param value an {@code long} to be written.
      */
-    final void writeLongAsIntLE(int index, long value) {
+    final void writeLongAsHighLowIntLE(int index, long value) {
+        // high
         buffer[index    ] = (byte) (value >>> 32);
         buffer[index + 1] = (byte) (value >>> 40);
         buffer[index + 2] = (byte) (value >>> 48);
         buffer[index + 3] = (byte) (value >>> 56);
+        // low
         buffer[index + 4] = (byte) value;
         buffer[index + 5] = (byte) (value >>> 8);
         buffer[index + 6] = (byte) (value >>> 16);
         buffer[index + 7] = (byte) (value >>> 24);
     }
 
+    /**
+     * Writes an {@code long} to the buffer as two integers of four bytes, each
+     * high byte first (big-endian). The long is written as the low 32-bits,
+     * then the high 32-bits.
+     *
+     * <p>Note: A HighLow big-endian output is the same as {@link #writeLongBE(int, long)}.
+     *
+     * @param index the index to start writing.
+     * @param value an {@code long} to be written.
+     */
+    final void writeLongAsLowHighIntBE(int index, long value) {
+        // low
+        buffer[index    ] = (byte) (value >>> 24);
+        buffer[index + 1] = (byte) (value >>> 16);
+        buffer[index + 2] = (byte) (value >>> 8);
+        buffer[index + 3] = (byte) value;
+        // high
+        buffer[index + 4] = (byte) (value >>> 56);
+        buffer[index + 5] = (byte) (value >>> 48);
+        buffer[index + 6] = (byte) (value >>> 40);
+        buffer[index + 7] = (byte) (value >>> 32);
+    }
+
     @Override
     public void close() throws IOException {
         try (OutputStream ostream = out) {
@@ -338,7 +404,7 @@
     /**
      * Create a new instance to write batches of data from
      * {@link UniformRandomProvider#nextLong()} to the specified output as two sequential
-     * {@code int} values.
+     * {@code int} values, high 32-bits then low 32-bits.
      *
      * <p>This will output the following bytes:</p>
      *
@@ -359,11 +425,43 @@
      * @return the data output
      */
     @SuppressWarnings("resource")
-    static RngDataOutput ofLongAsInt(OutputStream out, int size, ByteOrder byteOrder) {
+    static RngDataOutput ofLongAsHLInt(OutputStream out, int size, ByteOrder byteOrder) {
         // Ensure the buffer is positive and a factor of 8
         final int bytes = Math.max(size * 8, 8);
         return byteOrder == ByteOrder.LITTLE_ENDIAN ?
             new LLongAsIntRngDataOutput(out, bytes) :
             new BLongRngDataOutput(out, bytes);
     }
+
+    /**
+     * Create a new instance to write batches of data from
+     * {@link UniformRandomProvider#nextLong()} to the specified output as two sequential
+     * {@code int} values, low 32-bits then high 32-bits.
+     *
+     * <p>This will output the following bytes:</p>
+     *
+     * <pre>
+     * // Little-endian
+     * 76543210  ->  0123  4567
+     *
+     * // Big-endian
+     * 76543210  ->  3210  7654
+     * </pre>
+     *
+     * <p>This ensures the output from the generator is the original lower then upper order bits
+     * for each endianess.
+     *
+     * @param out Output stream.
+     * @param size Number of values to write.
+     * @param byteOrder Byte order.
+     * @return the data output
+     */
+    @SuppressWarnings("resource")
+    static RngDataOutput ofLongAsLHInt(OutputStream out, int size, ByteOrder byteOrder) {
+        // Ensure the buffer is positive and a factor of 8
+        final int bytes = Math.max(size * 8, 8);
+        return byteOrder == ByteOrder.LITTLE_ENDIAN ?
+            new LLongRngDataOutput(out, bytes) :
+            new BLongAsLoHiIntRngDataOutput(out, bytes);
+    }
 }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/Source64Mode.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/Source64Mode.java
new file mode 100644
index 0000000..357516a
--- /dev/null
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/Source64Mode.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rng.examples.stress;
+
+/**
+ * The mode to output a 64-bit source of randomness.
+ */
+enum Source64Mode {
+    /** The 64-bit output from nextLong. */
+    LONG,
+    /** The 32-bit output from nextInt. */
+    INT,
+    /** The high 32-bits, then low 32-bits of the 64-bit output. */
+    HI_LO,
+    /** The low 32-bits, then high 32-bits of the 64-bit output. */
+    LO_HI,
+    /** The low 32-bits of the 64-bit output. */
+    LO,
+    /** The high 32-bits of the 64-bit output. */
+    HI;
+}
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
index 62c4782..b24068e 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
@@ -153,25 +153,39 @@
                            "when passing using the standard sequence."})
     private boolean reverseBits;
 
-    /** Flag to use the upper 32-bits from the 64-bit long output. */
-    @Option(names = {"--high-bits"},
-            description = {"Use the upper 32-bits from the 64-bit long output.",
-                           "Takes precedent over --low-bits."})
-    private boolean longHighBits;
-
-    /** Flag to use the lower 32-bits from the 64-bit long output. */
-    @Option(names = {"--low-bits"},
-            description = {"Use the lower 32-bits from the 64-bit long output."})
-    private boolean longLowBits;
-
     /** Flag to use 64-bit long output. */
     @Option(names = {"--raw64"},
             description = {"Use 64-bit output (default is 32-bit).",
-                           "This requires a 64-bit testing application and native 64-bit generators.",
-                           "In 32-bit mode the output uses the upper then lower bits of 64-bit " +
-                           "generators sequentially, each appropriately byte reversed for the platform."})
+                           "This is ignored if not a native 64-bit generator.",
+                           "Set to true sets the source64 mode to LONG."})
     private boolean raw64;
 
+    /** Output mode for 64-bit long output.
+     *
+     * <p>Note: The default is set as the default caching implementation.
+     * It passes the full output of the RNG to the stress test application.
+     * Any combination random sources are performed on the full 64-bit output.
+     *
+     * <p>If using INT this will use the RNG's nextInt method.
+     * Any combination random sources are performed on the 32-bit output. Without
+     * a combination random source the output should be the same as the default if
+     * the generator uses the default caching implementation.
+     *
+     * <p>LONG and LO_HI should match binary output when LITTLE_ENDIAN. LONG and HI_LO
+     * should match binary output when BIG_ENDIAN.
+     *
+     * <p>Changing from HI_LO to LO_HI should not effect the stress test as many values are consumed
+     * per test. Using HI or LO may have a different outcome as parts of the generator output
+     * may be weak, e.g. the lower bits of linear congruential generators.
+     */
+    @Option(names = {"--source64"},
+            description = {"Output mode for 64-bit generators (default: ${DEFAULT-VALUE}).",
+                           "This is ignored if not a native 64-bit generator.",
+                           "In 32-bit mode the output uses a combination of upper and " +
+                           "lower bits of the 64-bit value.",
+                           "Valid values: ${COMPLETION-CANDIDATES}."})
+    private Source64Mode source64 = RNGUtils.getSource64Default();
+
     /** The random seed as a byte[]. */
     @Option(names = {"-x", "--hex-seed"},
             description = {"The hex-encoded random seed.",
@@ -481,6 +495,11 @@
                                        String basePath,
                                        Iterable<StressTestData> stressTestData,
                                        ProgressTracker progressTracker) {
+        // raw64 flag overrides the source64 mode
+        if (raw64) {
+            source64 = Source64Mode.LONG;
+        }
+
         final List<Runnable> tasks = new ArrayList<>();
         for (final StressTestData testData : stressTestData) {
             for (int trial = 1; trial <= testData.getTrials(); trial++) {
@@ -501,12 +520,17 @@
                 final byte[] seed = createSeed(testData.getRandomSource());
                 UniformRandomProvider rng = testData.createRNG(seed);
 
-                // Upper or lower bits from 64-bit generators must be created first.
-                // This will throw if not a 64-bit generator.
-                if (longHighBits) {
-                    rng = RNGUtils.createLongUpperBitsIntProvider(rng);
-                } else if (longLowBits) {
-                    rng = RNGUtils.createLongLowerBitsIntProvider(rng);
+                if (source64 == Source64Mode.LONG && !(rng instanceof RandomLongSource)) {
+                    throw new ApplicationException("Not a 64-bit RNG: " + rng);
+                }
+
+                // Upper or lower bits from 64-bit generators must be created first before
+                // any further combination operators.
+                // Note this does not test source64 != Source64Mode.LONG as the full long
+                // output split into hi-lo or lo-hi is supported by the RngDataOutput.
+                if (rng instanceof RandomLongSource &&
+                    (source64 == Source64Mode.HI || source64 == Source64Mode.LO || source64 == Source64Mode.INT)) {
+                    rng = RNGUtils.createIntProvider((UniformRandomProvider & RandomLongSource) rng, source64);
                 }
 
                 // Combination generators. Mainly used for testing.
@@ -669,7 +693,7 @@
             //    of a new one)
             // -- There are no pending tasks (i.e. the final submission or the end of a final task)
             if (completed >= total ||
-                (current >= nextReportTimestamp && (running == parallelTasks || pending == 0))) {
+                (current >= nextReportTimestamp && running == parallelTasks || pending == 0)) {
                 // Report
                 nextReportTimestamp = current + PROGRESS_INTERVAL;
                 final StringBuilder sb = createStringBuilderWithTimestamp(current, pending, running, completed);
@@ -991,7 +1015,7 @@
             final Process testingProcess = builder.start();
 
             // Use a custom data output to write the RNG.
-            try (RngDataOutput sink = RNGUtils.createDataOutput(rng, cmd.raw64,
+            try (RngDataOutput sink = RNGUtils.createDataOutput(rng, cmd.source64,
                 testingProcess.getOutputStream(), cmd.bufferSize, cmd.byteOrder)) {
                 for (;;) {
                     sink.write(rng);
@@ -1040,7 +1064,7 @@
                 .append(C).append("Native byte-order: ").append(ByteOrder.nativeOrder()).append(N)
                 .append(C).append("Output byte-order: ").append(cmd.byteOrder).append(N);
             if (rng instanceof RandomLongSource) {
-                sb.append(C).append("64-bit output: ").append(cmd.raw64).append(N);
+                sb.append(C).append("64-bit output: ").append(cmd.source64).append(N);
             }
             sb.append(C).append(N)
                 .append(C).append("Analyzer: ");
diff --git a/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RNGUtilsTest.java b/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RNGUtilsTest.java
new file mode 100644
index 0000000..55084e1
--- /dev/null
+++ b/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RNGUtilsTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rng.examples.stress;
+
+import org.apache.commons.rng.UniformRandomProvider;
+import org.apache.commons.rng.core.source64.SplitMix64;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for {@link RNGUtils}.
+ */
+class RNGUtilsTest {
+    @Test
+    void testCreateIntProviderLongThrows() {
+        final SplitMix64 rng = new SplitMix64(42);
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> RNGUtils.createIntProvider(rng, Source64Mode.LONG));
+    }
+
+    @Test
+    void testCreateIntProviderInt() {
+        final long seed = 236784264237894L;
+        final UniformRandomProvider rng1 = new SplitMix64(seed);
+        final UniformRandomProvider rng2 =
+            RNGUtils.createIntProvider(new SplitMix64(seed), Source64Mode.INT);
+        for (int i = 0; i < 50; i++) {
+            Assertions.assertEquals(rng1.nextInt(), rng2.nextInt());
+        }
+    }
+
+    @Test
+    void testCreateIntProviderLoHi() {
+        final long seed = 236784264237894L;
+        final UniformRandomProvider rng1 = new SplitMix64(seed);
+        final UniformRandomProvider rng2 =
+            RNGUtils.createIntProvider(new SplitMix64(seed), Source64Mode.LO_HI);
+        for (int i = 0; i < 50; i++) {
+            final long l = rng1.nextLong();
+            final int hi = (int) (l >>> 32);
+            final int lo = (int) l;
+            Assertions.assertEquals(lo, rng2.nextInt());
+            Assertions.assertEquals(hi, rng2.nextInt());
+        }
+    }
+
+    @Test
+    void testCreateIntProviderHiLo() {
+        final long seed = 2367234237894L;
+        final UniformRandomProvider rng1 = new SplitMix64(seed);
+        final UniformRandomProvider rng2 =
+            RNGUtils.createIntProvider(new SplitMix64(seed), Source64Mode.HI_LO);
+        for (int i = 0; i < 50; i++) {
+            final long l = rng1.nextLong();
+            final int hi = (int) (l >>> 32);
+            final int lo = (int) l;
+            Assertions.assertEquals(hi, rng2.nextInt());
+            Assertions.assertEquals(lo, rng2.nextInt());
+        }
+    }
+
+    @Test
+    void testCreateIntProviderHi() {
+        final long seed = 2367234237894L;
+        final UniformRandomProvider rng1 = new SplitMix64(seed);
+        final UniformRandomProvider rng2 =
+            RNGUtils.createIntProvider(new SplitMix64(seed), Source64Mode.HI);
+        for (int i = 0; i < 50; i++) {
+            final int hi = (int) (rng1.nextLong() >>> 32);
+            Assertions.assertEquals(hi, rng2.nextInt());
+        }
+    }
+
+    @Test
+    void testCreateIntProviderLo() {
+        final long seed = 2367234237894L;
+        final UniformRandomProvider rng1 = new SplitMix64(seed);
+        final UniformRandomProvider rng2 =
+            RNGUtils.createIntProvider(new SplitMix64(seed), Source64Mode.LO);
+        for (int i = 0; i < 50; i++) {
+            final int lo = (int) rng1.nextLong();
+            Assertions.assertEquals(lo, rng2.nextInt());
+        }
+    }
+
+    /**
+     * Test that the default source64 mode matches the nextInt implementation for a LongProvider.
+     * If this changes then the default mode should be updated. The value is used as
+     * the default for the stress test application.
+     */
+    @Test
+    void testCreateIntProviderDefault() {
+        final long seed = 236784264237894L;
+        final UniformRandomProvider rng1 = new SplitMix64(seed);
+        final UniformRandomProvider rng2 =
+            RNGUtils.createIntProvider(new SplitMix64(seed), RNGUtils.getSource64Default());
+        for (int i = 0; i < 50; i++) {
+            final int a = rng1.nextInt();
+            final int b = rng1.nextInt();
+            Assertions.assertEquals(a, rng2.nextInt());
+            Assertions.assertEquals(b, rng2.nextInt());
+        }
+    }
+}
diff --git a/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RngDataOutputTest.java b/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RngDataOutputTest.java
index b41a747..9c5d6a0 100644
--- a/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RngDataOutputTest.java
+++ b/commons-rng-examples/examples-stress/src/test/java/org/apache/commons/rng/examples/stress/RngDataOutputTest.java
@@ -84,33 +84,54 @@
     }
 
     @Test
-    void testLongAsIntBigEndian() throws IOException {
+    void testLongAsHLIntBigEndian() throws IOException {
         assertRngOutput(RandomSource.SPLIT_MIX_64,
-            // Convert SplitMix64 to an int provider so it is detected as requiring double the
+            // Convert to an int provider so it is detected as requiring double the
             // length output.
-            rng -> new IntProvider() {
-                @Override
-                public int next() {
-                    return rng.nextInt();
-                }
-            },
+            rng -> new HiLoCachingIntProvider(rng),
             RngDataOutputTest::writeInt,
-            RngDataOutput::ofLongAsInt, ByteOrder.BIG_ENDIAN);
+            RngDataOutput::ofLongAsHLInt, ByteOrder.BIG_ENDIAN);
     }
 
     @Test
-    void testLongAsIntLittleEndian() throws IOException {
+    void testLongAsHLIntLittleEndian() throws IOException {
         assertRngOutput(RandomSource.SPLIT_MIX_64,
             // Convert SplitMix64 to an int provider so it is detected as requiring double the
             // length output. Then reverse the bytes.
-            rng -> new IntProvider() {
+            rng -> new HiLoCachingIntProvider(rng) {
                 @Override
                 public int next() {
-                    return Integer.reverseBytes(rng.nextInt());
+                    return Integer.reverseBytes(super.next());
                 }
             },
             RngDataOutputTest::writeInt,
-            RngDataOutput::ofLongAsInt, ByteOrder.LITTLE_ENDIAN);
+            RngDataOutput::ofLongAsHLInt, ByteOrder.LITTLE_ENDIAN);
+    }
+
+
+    @Test
+    void testLongAsLHIntBigEndian() throws IOException {
+        assertRngOutput(RandomSource.SPLIT_MIX_64,
+            // Convert to an int provider so it is detected as requiring double the
+            // length output.
+            rng -> new LoHiCachingIntProvider(rng),
+            RngDataOutputTest::writeInt,
+            RngDataOutput::ofLongAsLHInt, ByteOrder.BIG_ENDIAN);
+    }
+
+    @Test
+    void testLongAsLHIntLittleEndian() throws IOException {
+        assertRngOutput(RandomSource.SPLIT_MIX_64,
+            // Convert to an int provider so it is detected as requiring double the
+            // length output. Then reverse the bytes.
+            rng -> new LoHiCachingIntProvider(rng) {
+                @Override
+                public int next() {
+                    return Integer.reverseBytes(super.next());
+                }
+            },
+            RngDataOutputTest::writeInt,
+            RngDataOutput::ofLongAsLHInt, ByteOrder.LITTLE_ENDIAN);
     }
 
     private static void writeInt(DataOutputStream sink, UniformRandomProvider rng) {
@@ -212,4 +233,56 @@
         }
         return out.toByteArray();
     }
+
+    private static class LoHiCachingIntProvider extends IntProvider {
+        private long source = -1;
+        private final UniformRandomProvider rng;
+
+        LoHiCachingIntProvider(UniformRandomProvider rng) {
+            this.rng = rng;
+        }
+
+        @Override
+        public int next() {
+            long next = source;
+            if (next < 0) {
+                // refill
+                next = rng.nextLong();
+                // store hi
+                source = next >>> 32;
+                // extract low
+                return (int) next;
+            }
+            final int v = (int) next;
+            // reset
+            source = -1;
+            return v;
+        }
+    }
+
+    private static class HiLoCachingIntProvider extends IntProvider {
+        private long source = -1;
+        private final UniformRandomProvider rng;
+
+        HiLoCachingIntProvider(UniformRandomProvider rng) {
+            this.rng = rng;
+        }
+
+        @Override
+        public int next() {
+            long next = source;
+            if (next < 0) {
+                // refill
+                next = rng.nextLong();
+                // store low
+                source = next & 0xffff_ffffL;
+                // extract hi
+                return (int) (next >>> 32);
+            }
+            final int v = (int) next;
+            // reset
+            source = -1;
+            return v;
+        }
+    }
 }
diff --git a/commons-rng-examples/examples-stress/stress_test.md b/commons-rng-examples/examples-stress/stress_test.md
index dcd0f31..647a5d7 100644
--- a/commons-rng-examples/examples-stress/stress_test.md
+++ b/commons-rng-examples/examples-stress/stress_test.md
@@ -108,7 +108,7 @@
 Test platform Endianness
 ------------------------
 
-The stress test application will output raw binary data for generated integers or longs. 
+The stress test application will output raw binary data for generated integers or longs.
 An integer is 4 bytes and a long is 8 bytes and thus the byte order or [Endianness](https://en.wikipedia.org/wiki/Endianness) of the data
 must be correct for the test application. The stress test application can support either big-endian
 or little-endian format. The application will auto-detect the platform and will default to output
@@ -170,7 +170,7 @@
 | executable | The test tool | dieharder, stdin2testu01, PractRand |
 | ... | Arguments for the test tool | dieharder: -a -g 200 -Y 1 -k 2 <br/> stdin2testu01: SmallCrush, Crush, BigCrush <br/> RNG_test stdin32 -tf 1 -te 0 -tlmin 1KB -tlmax 4TB |
 
-The `stress` command defaults for other options that can be changed, for example the output
+The `stress` command defaults for other options can be changed, for example the output
 results file prefix, the number of concurrent tasks, byte-order or the number of trials per
 generator.
 Use the `--help` option to show the available options.
@@ -250,24 +250,42 @@
         java -jar target/examples-stress.jar results \
               target/tu_* \
               target/dh_* \
-              target/pr_* \
+              target/pr_*
 
 Various formats are available. Use the `--help` option to show the available options.
 
 Test 64-bit generators
 ----------------------
 
-The available random generators output either 32-bits or 64-bits per cycle. 
+The available random generators output either 32-bits or 64-bits per cycle.
 
 Any application that supports 64-bit generators and should be tested using the `--raw64`
 output mode of the `stress` command. See the example for running tests using **PractRand**
 for details.
 
 Any application that supports 32-bit generators can be tested using different subsets of the
-64-bit output. For example the test applications **Dieharder** and **TestU01** require 32-bit input.
-The standard method for a 64-bit generator is to use the upper and then lower 32-bits of each
-64-bit output. The stress test application has options to use only the upper or the lower 32-bits
-for testing. These can then be bit-reversed or byte-reversed if desired.
+64-bit output using the `--source64` option. For example the test applications **Dieharder**
+and **TestU01** require 32-bit input.
+The standard method for a 64-bit generator is to use the full 64-bits of output in the order
+provided by the Commons RNG core caching implementation of the `nextInt` method. The stress
+test application has options to use the following parts of the 64-bit output:
+
+| source64  | Description |
+| --------- | ---------- |
+| LONG | Use the full 64-bit output. This is equivalent to using the `--raw64` mode. |
+| INT | Use the 32-bit output from the RNG implementation of nextInt. |
+| HI_LO | Use the upper 32-bits, then lower 32-bits of the 64-bit output. |
+| LO_HI | Use the lower 32-bits, then upper 32-bits of the 64-bit output. |
+| HI | Use the upper 32-bits of the 64-bit output. |
+| LO | Use the lower 32-bits of the 64-bit output. |
+
+Note: The default uses an explicit mode rather than INT so that it is recorded in the stress
+test output file. If the RNG uses the default implementation for `nextInt` then output
+from INT should match LO_HI.
+
+On some platforms the LONG setting is matched by a split of the upper and lower parts.
+The binary output from LONG should match LO_HI if using little-endian format;
+it should match HI_LO if using big-endian format.
 
 The `list` command can output available generators by provider type. For example to output the
 64-bit providers to a `rng64.list` file:
@@ -280,11 +298,14 @@
 
         java -jar target/examples-stress.jar stress \
               --list rng64.list \
-              --low-bits \
+              --source64 LO \
               --reverse-bits \
               --prefix target/tu_lo_r_ \
               ./stdin2testu01 \
               BigCrush
 
-If a 32-bit provider is used with the `--low-bits` or `--upper-bits` options then an error
-message is shown.
+If a 32-bit provider is used with the `--source64=LONG` or `--raw64` options then
+an error message is shown as this is explicitly for 64-bit output. Other `source64`
+options split the 64-bit output for testing with a 32-bit stress test application. These
+options are ignored for any 32-bit provider; this allows testing 64-bit and 32-bit
+providers in the same batch execution.