Java 生成包含在指定值区间中的随机浮点值的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40431966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to generate a random float value included into a specified value interval?
提问by AndreaNobili
I want to generate a random float value in Java. The value has to be within a specific range of possible values.
我想在 Java 中生成一个随机浮点值。该值必须在可能值的特定范围内。
For example, I have to generate a random value that is in the following range:
例如,我必须生成一个在以下范围内的随机值:
MIN: 41,815080
MAX: 41,829191
These values happen to represent a range of possible longitudes on a map, but the question applies more generally.
这些值恰好代表地图上可能的经度范围,但这个问题更普遍。
What is a smart way to do it?
有什么聪明的方法来做到这一点?
回答by Bohemian
For a random value within a range, the formula is:
对于范围内的随机值,公式为:
double random = min + Math.random() * (max - min);
This basic formula is constant no matter what you use to generate random numbers.
无论您使用什么来生成随机数,这个基本公式都是不变的。
Math.random()
provides moderately well distributed numbers, but you can replace it with whatever random number generator you want, for example (slightly better):
Math.random()
提供中等分布的数字,但你可以用你想要的任何随机数生成器替换它,例如(稍微好一点):
Random r = new Random();
double random = min + r.nextDouble() * (max - min);
or if you really want a float
:
或者如果你真的想要一个float
:
float random = min + r.nextFloat() * (max - min);
Or you can a more exotic 3rd party library.
或者您可以使用更具异国情调的 3rd 方库。
回答by Yogesh
If you want to generate random float values try this:
如果要生成随机浮点值,请尝试以下操作:
import java.util.Random;
public static float randFloat(float min, float max) {
Random rand = new Random();
return rand.nextFloat() * (max - min) + min;
}
Hope this helped.
希望这有帮助。
回答by Manthan_Admane
Code:
代码:
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();
}
}
回答by Finn
I know that this question is over a year old, but the other answers here are missing important points. The best way to generate a random floating-point value in Java (assuming you don't need a specific seed and you don't need to be cryptographically secure) is the ThreadLocalRandom
class.
我知道这个问题已经有一年多了,但是这里的其他答案缺少重要的点。在 Java 中生成随机浮点值的最佳方法(假设您不需要特定的种子并且不需要加密安全)是ThreadLocalRandom
类。
For example, if you want a method that generates random numbers between two other numbers, you could write it like this:
例如,如果你想要一个在其他两个数字之间生成随机数的方法,你可以这样写:
public static double generateRandomDouble(double min, double max) {
return ThreadLocalRandom.current().nextDouble(min, max);
}
- The problem with
Math.random
is that it results in contention. In other words, if your code is being run concurrently with any other code that usesMath.random
, your random number may have to be recomputed. - The problem with
new Random()
is that it's creating a newRandom
instance every time it's called, which is extra work and more verbose. - The problem with both of these methods is that they force youto do the extra math to scale it to the desired range, making your code less readable and more error-prone. The
ThreadLocalRandom
class has a very convenientnextDouble
overload that lets you specify an "origin" and "bound," meaning minimum and maximum. - Another problem with both of these methods is that they're imprecise. Because you're doing the scaling, you need to account for the rounding problems that are inherent in floating-point arithmetic. In fact, all of the other answers to this question will sometimes produce answers equal to max.
- 问题
Math.random
在于它会导致争用。换句话说,如果您的代码与使用 的任何其他代码同时运行Math.random
,则您的随机数可能需要重新计算。 - 问题
new Random()
在于Random
每次调用它时都会创建一个新实例,这是额外的工作并且更加冗长。 - 这两种方法的问题在于它们迫使您进行额外的数学运算以将其缩放到所需的范围,从而使您的代码可读性较差且更容易出错。该
ThreadLocalRandom
班有一个非常方便的nextDouble
过载,让你指定一个“原点”和“约束”,意思是最小值和最大值。 - 这两种方法的另一个问题是它们不精确。因为要进行缩放,所以需要考虑浮点运算中固有的舍入问题。事实上,这个问题的所有其他答案有时都会产生等于 max 的答案。
In the code above, I am making two assumptions. First, you want the lower bound to be inclusive and the upper bound to be exclusive. This assumption is rather trivial, because the probability of actually landing on the boundary is very small. This is also what the other answers are attempting to do (though they sometimes produce answers equal to max, unlike mine). The second assumption I make is that by a "random float value," you mean a floating-point value, which I assumed based on the fact that you tagged the question with floating-point. Thus, I gave a method that returns a double
, which is a double-precision floating-point value, and what you'll typically use in Java for floating-point values. However, if you meant to specify a float
primitive, you can use the following method:
在上面的代码中,我做了两个假设。首先,您希望包含的下限和不包含的上限。这个假设相当微不足道,因为实际降落在边界上的概率非常小。这也是其他答案试图做的事情(尽管他们有时会产生等于 max 的答案,这与我的不同)。第二个假设我提出的是,“随机浮点值,”你的意思是一个浮点值,我以为根据你所标记与问题其实浮点。因此,我给出了一个返回 a 的方法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;
}
There is unfortunately no nextFloat
overload on ThreadLocalRandom
, presumably because they expect very few people to need random float
s. To write this method correctly, you must correct for floating-point rounding problems. Thus, I would strongly recommend that you use the version that produces a double
.
不幸的是没有nextFloat
超载ThreadLocalRandom
,大概是因为他们预计很少有人需要 random float
s。要正确编写此方法,您必须更正浮点舍入问题。因此,我强烈建议您使用生成double
.
In conclusion, you should neveruse Math.random
, and you shouldn't create a new Random
instance every time you need to generate a random number (unless, of course, you need a specific seed). When generating random numbers, default to the ThreadLocalRandom
class.
总之,您永远不应该使用Math.random
,也不应该在Random
每次需要生成随机数时都创建一个新实例(当然,除非您需要一个特定的种子)。生成随机数时,默认为ThreadLocalRandom
类。