# Add uniform and spatially equidistributed bounded double streams to RandomGenerator

XMLWordPrintable

#### Details

• CSR
• Resolution: Approved
• P4
• None
• minimal
• This is an additional default method to a public interface. The name and type signature has been chosen to considerably lower the risk of conflicts with implementations outside the JDK.
• Java API
• SE

## Summary

Applying an affine transform to a uniform and spatially equidistributed random float/double in the range [0, 1) to obtain values in a user specified range [left, right), as currently done in the JDK, results in a slightly deformed distribution due to rounding error.

## Problem

See JDK-8302987 for a more detailed description of the problem.

## Solution

Add a new public API point to java.util.random.RandomGenerator to obtain a stream that generates a uniform and equidistributed flow of doubles in a given interval.

## Specification

``````+    /**
+     * Returns an effectively unlimited stream of pseudorandomly chosen
+     * {@code double} values, where each value is between the specified
+     * {@code left} boundary and the specified {@code right} boundary.
+     * The {@code left} boundary is included as indicated by
+     * {@code isLeftIncluded}; similarly, the {@code right} boundary is included
+     * as indicated by {@code isRightIncluded}.
+     *
+     * <p>The stream potentially produces all multiples <i>k</i> &delta;
+     * (<i>k</i> integer) lying in the interval specified by the parameters,
+     * where &delta; > 0 is the smallest number for which all these multiples
+     * are exact {@code double}s.
+     * They are therefore all equidistant.
+     * The uniformity of the distribution of the {@code double}s produced by
+     * the stream depends on the quality of the underlying {@link #nextLong(long)}.
+     *
+     * @implSpec The default implementation first determines the &delta; above.
+     * It then computes both the smallest integer <i>k</i><sub><i>l</i></sub>
+     * such that <i>k</i><sub><i>l</i></sub> &delta; lies <em>inside</em>
+     * the given interval, and the smallest integer <i>n</i> > 0 such that
+     * (<i>k</i><sub><i>l</i></sub> + <i>n</i>) &delta; lies
+     * <em>outside</em> the interval.
+     * Finally, it returns a stream which generates the {@code double}s
+     * according to (<i>k</i><sub><i>l</i></sub> + {@code nextLong(}<i>n</i>{@code )})
+     * &delta;.
+     * The stream never produces {@code -0.0}, although it may produce
+     * {@code 0.0} if the specified interval contains 0.
+     *
+     * @param left the left boundary
+     * @param right the right boundary
+     * @param isLeftIncluded whether the {@code left} boundary is included
+     * @param isRightIncluded whether the {@code right} boundary is included
+     *
+     * @return a stream of pseudorandomly chosen {@code double} values, each
+     *         between {@code left} and {@code right}, as specified above.
+     *
+     * @throws IllegalArgumentException if {@code left} is not finite,
+     *         or {@code right} is not finite, or if the specified interval
+     *         is empty.
+     */
+    default DoubleStream equiDoubles(double left, double right,
+        boolean isLeftIncluded, boolean isRightIncluded) {``````

#### People

Raffaello Giulietti
Raffaello Giulietti