mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8202449: overflow handling in Random.doubles
Reviewed-by: darcy
This commit is contained in:
parent
c15e10fb6c
commit
c8cff1bd6f
5 changed files with 82 additions and 71 deletions
|
@ -256,7 +256,8 @@ public class Random implements RandomGenerator, java.io.Serializable {
|
|||
private static final long addend = 0xBL;
|
||||
private static final long mask = (1L << 48) - 1;
|
||||
|
||||
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
|
||||
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << Double.PRECISION)
|
||||
private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << Float.PRECISION)
|
||||
|
||||
/**
|
||||
* Creates a new random number generator. This constructor sets
|
||||
|
@ -598,12 +599,12 @@ public class Random implements RandomGenerator, java.io.Serializable {
|
|||
* low-order bit of the significand would be 0 than that it would be 1.]
|
||||
*
|
||||
* @return the next pseudorandom, uniformly distributed {@code float}
|
||||
* value between {@code 0.0} and {@code 1.0} from this
|
||||
* value between {@code 0.0f} and {@code 1.0f} from this
|
||||
* random number generator's sequence
|
||||
*/
|
||||
@Override
|
||||
public float nextFloat() {
|
||||
return next(24) / ((float)(1 << 24));
|
||||
return next(Float.PRECISION) * FLOAT_UNIT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -644,7 +645,7 @@ public class Random implements RandomGenerator, java.io.Serializable {
|
|||
*/
|
||||
@Override
|
||||
public double nextDouble() {
|
||||
return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
|
||||
return (((long)(next(Double.PRECISION - 27)) << 27) + next(27)) * DOUBLE_UNIT;
|
||||
}
|
||||
|
||||
private double nextNextGaussian;
|
||||
|
@ -1070,26 +1071,12 @@ public class Random implements RandomGenerator, java.io.Serializable {
|
|||
* pseudorandom {@code double} values, each conforming to the given origin
|
||||
* (inclusive) and bound (exclusive).
|
||||
*
|
||||
* <p>A pseudorandom {@code double} value is generated as if it's the result
|
||||
* of calling the following method with the origin and bound:
|
||||
* <pre> {@code
|
||||
* double nextDouble(double origin, double bound) {
|
||||
* double r = nextDouble();
|
||||
* r = r * (bound - origin) + origin;
|
||||
* if (r >= bound) // correct for rounding
|
||||
* r = Math.nextDown(bound);
|
||||
* return r;
|
||||
* }}</pre>
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code double} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code streamSize} is less than zero,
|
||||
* or {@code randomNumberOrigin} is not finite,
|
||||
* or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
|
@ -1101,18 +1088,7 @@ public class Random implements RandomGenerator, java.io.Serializable {
|
|||
* Returns an effectively unlimited stream of pseudorandom {@code
|
||||
* double} values, each conforming to the given origin (inclusive) and bound
|
||||
* (exclusive).
|
||||
*
|
||||
* <p>A pseudorandom {@code double} value is generated as if it's the result
|
||||
* of calling the following method with the origin and bound:
|
||||
* <pre> {@code
|
||||
* double nextDouble(double origin, double bound) {
|
||||
* double r = nextDouble();
|
||||
* r = r * (bound - origin) + origin;
|
||||
* if (r >= bound) // correct for rounding
|
||||
* r = Math.nextDown(bound);
|
||||
* return r;
|
||||
* }}</pre>
|
||||
*
|
||||
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
||||
*
|
||||
|
@ -1120,8 +1096,7 @@ public class Random implements RandomGenerator, java.io.Serializable {
|
|||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code double} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
package java.util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGenerator.SplittableGenerator;
|
||||
|
@ -551,9 +550,7 @@ public final class SplittableRandom implements RandomGenerator, SplittableGenera
|
|||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code double} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero, or {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
|
||||
|
@ -572,8 +569,7 @@ public final class SplittableRandom implements RandomGenerator, SplittableGenera
|
|||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code double} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
|
||||
|
|
|
@ -540,10 +540,7 @@ public interface RandomGenerator {
|
|||
*
|
||||
* @throws IllegalArgumentException if {@code origin} is not finite,
|
||||
* or {@code bound} is not finite, or {@code origin}
|
||||
* is greater than or equal to {@code bound}, or
|
||||
* the difference between {@code bound} and {@code origin}
|
||||
* is so large that it cannot be represented as a finite
|
||||
* {@code float} value
|
||||
* is greater than or equal to {@code bound}
|
||||
*
|
||||
* @implSpec The default implementation verifies that the {@code origin}
|
||||
* and {@code bound} are valid then invokes {@code nextFloat()}
|
||||
|
@ -606,11 +603,8 @@ public interface RandomGenerator {
|
|||
*
|
||||
* @throws IllegalArgumentException if {@code origin} is not finite,
|
||||
* or {@code bound} is not finite, or {@code origin}
|
||||
* is greater than or equal to {@code bound}, or
|
||||
* the difference between {@code bound} and {@code origin}
|
||||
* is so large that it cannot be represented as a finite
|
||||
* {@code double} value
|
||||
*
|
||||
* is greater than or equal to {@code bound}
|
||||
|
||||
* @implSpec The default implementation verifies that the {@code origin}
|
||||
* and {@code bound} are valid, then invokes {@code nextDouble()}
|
||||
* scaling and translating the result to fit between {@code origin}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue