This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit 0389632561ca096624974c4e571448453f2819bd
Author: Alex Herbert <[email protected]>
AuthorDate: Fri Feb 13 12:04:40 2026 +0000

    Add benchmark for generation of an open interval (0, 1)
---
 .../core/FloatingPointGenerationPerformance.java   | 68 +++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git 
a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/core/FloatingPointGenerationPerformance.java
 
b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/core/FloatingPointGenerationPerformance.java
index 1fdc0672..e2628856 100644
--- 
a/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/core/FloatingPointGenerationPerformance.java
+++ 
b/commons-rng-examples/examples-jmh/src/main/java/org/apache/commons/rng/examples/jmh/core/FloatingPointGenerationPerformance.java
@@ -99,7 +99,12 @@ public class FloatingPointGenerationPerformance {
         // 0x300L = 256 + 512 = 768
         // 0x0ff  = 255
         // This makes a number in the range 1.0 to 2.0 so subtract 1.0
-        return Double.longBitsToDouble(0x3ffL << 52 | source.nextLong() >>> 
12) - 1.0;
+        //
+        // Note: This variant using a long constant can be slower:
+        // Double.longBitsToDouble((source.nextLong() >>> 12) | 
0x3ff0000000000001L) - 1.0
+        // It matches the performance of nextOpenDoubleUsingBitsToDouble so is 
not
+        // formally included as a variant.
+        return Double.longBitsToDouble((source.nextLong() >>> 12) | (0x3ffL << 
52)) - 1.0;
     }
 
     /**
@@ -120,6 +125,67 @@ public class FloatingPointGenerationPerformance {
         return (source.nextLong() >>> 11) * 0x1.0p-53d; // 1.0 / (1L << 53)
     }
 
+    // Methods for generation of a double in the open interval (0, 1).
+    // These are similar to the methods above with addition of a 1-bit
+    // at the end of the mantissa to avoid zero.
+
+    /**
+     * @param source the source
+     * @return the double
+     */
+    @Benchmark
+    public double nextOpenDoubleUsingBitsToDouble(LongSource source) {
+        return Double.longBitsToDouble((source.nextLong() >>> 12) | 
0x3ff0000000000001L) - 1.0;
+    }
+
+    /**
+     * @param source the source
+     * @return the double
+     */
+    @Benchmark
+    public double nextOpenDoubleUsingMultiply52bits(LongSource source) {
+        return ((source.nextLong() >>> 12) + 0.5) * 0x1.0p-52d;
+    }
+
+    /**
+     * @param source the source
+     * @return the double
+     */
+    @Benchmark
+    public double nextOpenDoubleUsingMultiply53bits(LongSource source) {
+        return ((source.nextLong() >>> 11) | 1) * 0x1.0p-53d;
+    }
+
+    /**
+     * @param source the source
+     * @return the double
+     */
+    @Benchmark
+    public double nextOpenDoubleUsingRejection(LongSource source) {
+        // Methods adding a single trailing 1-bit will return 2^52 possible 
doubles.
+        // Using rejection of zero allows return of 2^53 - 1 possible doubles.
+        long a;
+        do {
+            a = source.nextLong() >>> 11;
+        } while (a == 0);
+        return a * 0x1.0p-53d;
+    }
+
+    /**
+     * @param source the source
+     * @return the double
+     */
+    @Benchmark
+    public double nextOpenDoubleUsingRecursion(LongSource source) {
+        // Rejection by recursion will cause a stack overflow error if the 
source
+        // is broken. This uses floating point comparison.
+        final double a = (source.nextLong() >>> 11) * 0x1.0p-53d;
+        if (a == 0.0) {
+            return nextOpenDoubleUsingRejection(source);
+        }
+        return a;
+    }
+
     /**
      * @param source the source
      * @return the int

Reply via email to