我需要生成在区间
我找到了多种类似的区间生成方法,例如:
但是上限总是 不包括 的,我需要它也包括在内。
[-0.5, 0.5]
内的随机实数,包括两个边界点。我找到了多种类似的区间生成方法,例如:
-0.5 + Math.random()
但是上限总是 不包括 的,我需要它也包括在内。
0.5
必须在范围内。实现这个的一种方法是创建一个从-500到500的随机int
,然后将其除以1000。
int max = 500;
int min = -500;
int randomInt = rand.nextInt((max - min) + 1) + min;
float randomNum = randomInt / 1000.00f;
System.out.println(randomNum);
double min = -0.5;
double max = 0.5;
double epsilon = 1;
while (max + epsilon / 2 > max) {
epsilon /= 2;
}
Random random = ThreadLocalRandom.current();
DoubleStream randomDoubles = random.doubles(min, max + epsilon);
double min = -0.5;
double max = 0.5;
double maxPlusEpsilon = Double.longBitsToDouble(Double.doubleToLongBits(max) + 1L)
Random random = ThreadLocalRandom.current();
DoubleStream randomDoubles = random.doubles(min, maxPlusEpsilon);
0.5 + Double.MIN_VALUE > 0.5
的结果为 false
。要找到下一个较大的数字,必须在该数字的确切邻域中找出 epsilon 值。 - Peter Walsermax = Double.longBitsToDouble(Double.doubleToLongBits(max) + 1L);
来获取实际的max+epsilon。 - DodgyCodeExceptionDouble.longBitsToDouble(0x3ff0000000000000L) // 1.0
Double.longBitsToDouble(0x3ffFFFFFFFFFFFFFL) // 1.9999999999999998
Double.longBitsToDouble(0x4000000000000000L) // 2.0
long l = ThreadLocalRandom.current().nextLong(0x0010000000000001L);
double r = Double.longBitsToDouble(l + 0x3ff0000000000000L) - 1.5;
这种技术仅适用于跨越二进制数字的范围(1、2、4、8、0.5、0.25等),但对于这些范围,该方法可能是最有效和准确的。此示例针对范围为1进行调整。对于不跨越二进制范围的范围,您仍然可以使用此技术来获得不同的范围。将该技术应用于在范围[0, 1]内获取数字,并将结果缩放到所需的范围。这样做会产生可忽略的精度损失,其结果精度实际上与Random.nextDouble(double, double)
相同。
对于其他范围,请执行此代码以查找偏移量:
double span = 0.125;
if (!(span > 0.0) || (Double.doubleToLongBits(span) & 0x000FFFFFFFFFFFFFL) != 0)
throw new IllegalArgumentException("'span' is not a binary number: " + span);
if (span * 2 >= Double.MAX_VALUE)
throw new IllegalArgumentException("'span' is too large: " + span);
System.out.println("Offset: 0x" + Long.toHexString(Double.doubleToLongBits(span)));
span
以获得从0开始的值。根据HOW GOD SPIDERS的答案,这里是一个可直接使用的函数:
public static double randomFloat(double minInclusive, double maxInclusive, double precision) {
int max = (int)(maxInclusive/precision);
int min = (int)(minInclusive/precision);
Random rand = new Random();
int randomInt = rand.nextInt((max - min) + 1) + min;
double randomNum = randomInt * precision;
return randomNum;
}
那么
System.out.print(randomFloat(-0.5, 0.5, 0.01));
@OH GOD SPIDERS' answer 的回答给了我一个想法,开发出一种可以提供更高精度的答案。将 nextLong()
转换为 double
时,可以获得介于 MIN_VALUE 和 MAX_VALUE 之间的值,精度足够高。
double randomNum = (rand.nextLong() / 2.0) / Long.MAX_VALUE;
证明边界是包含的:
assert (Long.MIN_VALUE/2.0)/Long.MAX_VALUE == -0.5;
assert (Long.MAX_VALUE/2.0)/Long.MAX_VALUE == 0.5;
Random.nextDouble() 方法返回一个 [0, 1] 范围内的值。因此,如果要将其映射到 [-0.5, 0.5] 范围内,只需减去 0.5。
您可以使用以下代码来获得所需的输出结果:
double value = r.nextDouble() - 0.5;
Math.random()
实际上调用了nextDouble()
。 - DodgyCodeException
(-0.5; 0.5)
жҲ–й—ӯеҢәй—ҙ[-0.5; 0.5]
пјҹж•°еӯҰдёҠи®ІпјҢ[-0.5; 0.5]
дёҚжҳҜдёҖдёӘеҢәй—ҙпјҢиҖҢжҳҜдёҖз»„ж•°еӯ—гҖӮжҲ‘е°Ҷж¶ҰиүІзҝ»иҜ‘并дҝқжҢҒеҺҹж„ҸпјҢдёҚжҸҗдҫӣд»»дҪ•и§ЈйҮҠжҲ–йўқеӨ–дҝЎжҒҜгҖӮ - Nikolas Charalambidis