我想在Java中生成随机浮点值。该值必须在可能值的特定范围内。
例如,我必须生成一个在以下范围内的随机值:
MIN: 41,815080
MAX: 41,829191
这些值恰好代表地图上可能存在的经度范围,但问题更为普遍。
这是一种聪明的方法吗?
答案 0 :(得分:35)
对于范围内的随机值,公式为:
double random = min + Math.random() * (max - min);
无论您使用什么来生成随机数,这个基本公式都是常量。
Math.random()
提供中等分布的数字,但您可以将其替换为您想要的任何随机数生成器,例如(稍好一点):
Random r = new Random();
double random = min + r.nextDouble() * (max - min);
或者如果你真的想要float
:
float random = min + r.nextFloat() * (max - min);
或者你可以拥有一个更具异国情调的第三方图书馆。
答案 1 :(得分:10)
如果要生成随机浮点值,请尝试:
import java.util.Random;
public static float randFloat(float min, float max) {
Random rand = new Random();
float result = rand.nextFloat() * (max - min) + min;
return result;
}
希望这会有所帮助。
答案 2 :(得分:1)
代码:
import java.util.Scanner;
public class Hello
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
double max,min,randfloat;
System.out.println("Enter minimum :");
min=sc.nextDouble();
System.out.println("Enter maximum :");
max=sc.nextDouble();
randfloat=(Math.random())*(max-min)+min; //Math.random() generates random value between 0 and 1
System.out.println("Random float value generated is: "+randfloat);
sc.close();
}
}
答案 3 :(得分:1)
我知道这个问题已有一年多的历史了,但是这里的其他答案都缺少重点。在Java中生成随机浮点值的最佳方法(假设您不需要特定的种子并且不需要cryptographically secure)是ThreadLocalRandom
类。
例如,如果您想要一个在其他两个数字之间生成随机数的方法,则可以这样编写:
public static double generateRandomDouble(double min, double max) {
return ThreadLocalRandom.current().nextDouble(min, max);
}
Math.random
的问题在于it results in contention。换句话说,如果您的代码与使用Math.random
的任何其他代码同时运行,则可能必须重新计算您的随机数。new Random()
的问题在于,每次调用它都会创建一个新的Random
实例,这是额外的工作,而且更加冗长。ThreadLocalRandom
类有一个非常方便的nextDouble
重载,可让您指定“起点”和“界限”,表示最小值和最大值。在上面的代码中,我有两个假设。首先,您希望下限是包含的,上限是排除的。该假设相当微不足道,因为实际降落在边界上的概率非常小。这也是其他答案正在尝试做的事情(尽管它们有时会产生等于max的答案,这与我的答案不同)。我做出的第二个假设是,“随机浮点值”是指浮点值,基于您用floating-point标记问题的事实,我假定了该点。因此,我给出了一种返回double
的方法,该值是双精度浮点值,以及您在Java中通常使用的浮点值。但是,如果要指定float
原语,则可以使用以下方法:
public static float generateRandomFloat(float min, float max) {
if (min >= max)
throw new IllegalArgumentException("max must be greater than min");
float result = ThreadLocalRandom.current().nextFloat() * (max - min) + min;
if (result >= max) // correct for rounding
result = Float.intBitsToFloat(Float.floatToIntBits(max) - 1);
return result;
}
不幸的是,nextFloat
上没有ThreadLocalRandom
过载,大概是因为他们希望很少有人需要随机的float
。若要正确编写此方法,必须纠正浮点舍入问题。因此,我强烈建议您使用产生double
的版本。
最后,您应该从不使用Math.random
,并且每次需要生成随机数时都不应创建新的Random
实例(除非当然,您需要特定的种子)。生成随机数时,默认为ThreadLocalRandom
类。