[英]Generate a random number and sort odd and even numbers using JOptionPane
[英]How to efficiently generate only odd (or even) random numbers?
通过查看关于仅生成奇数或偶数的其他问题,我很好奇哪种方法(在速度方面)最有效。
例如,假设我想生成许多奇数,范围从1(含)到1000(不含); 对于每次迭代,我通常使用的方法如下:
2
1
有没有更好的方法?
我今天偶然发现了这种方法,并且在StackOverflow上找不到用于生成偶数或奇数的任何用法。
该方法利用以下事实:二进制的所有偶数(包括0
)的最低有效位均设置为0
而所有奇数的最低有效位均设置为1
。
因此,要生成一个奇数,我们可以简单地生成一个期望范围内的随机数,然后按位或1
生成一个随机数:
ThreadLocalRandom.current().nextInt(0, 1_000) | 1
使用这种方法,如果生成器选择了一个奇数,则将其保留下来。 但是,如果选择了偶数,则将其按1
进行按位或运算实质上会使其递增。
同样,要生成介于2
(含)和1000
(不含)之间的偶数,则只需要清除最低有效位即可。 为此,我们可以简单地按位运算-然后用-2
表示值:
ThreadLocalRandom.current().nextInt(2, 1_000) & -2
使用这种方法,如果生成器选择一个偶数,则它会被保留。 但是,如果选择了奇数,则按位加“ -2
实际上会使它递减。
这些方法的工作负值完美的罚款,并long
为好。
这是JMH基准测试,比较了生成1
(含)和1000
(不含)之间的奇数的两种方法:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 20, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(5)
public class MyBenchmark {
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
@Benchmark
public int oldMethod() {
return RANDOM.nextInt(0, 500) * 2 + 1;
}
@Benchmark
public int newMethod() {
return RANDOM.nextInt(0, 1000) | 1;
}
}
结果:
Benchmark Mode Cnt Score Error Units
MyBenchmark.newMethod avgt 100 6.079 ± 0.137 ns/op
MyBenchmark.oldMethod avgt 100 6.325 ± 0.009 ns/op
oldMethod
可以稍微通过使用能够提高<< 1
代替* 2
,但newMethod
仍然是稍快。
您的2n + 1
方法很好。 如果愿意,您可以使用流并将其包装在帮助程序方法中,以便于使用:
import java.util.Random;
public static IntStream randomOdds(int from, int upTo) {
return new Random().ints(from/2, upTo/2).map(n -> 2*n + 1);
}
用法:
randomOdds(1, 1000).limit(20).forEach(System.out::println);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.