如何获取Random.nextLong返回的所有可能值? [英] How to obtain all possible values returnable by Random.nextLong?

查看:78
本文介绍了如何获取Random.nextLong返回的所有可能值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Random#nextLong()文档指出,此方法不会返回所有可能的 long 值:

The Random#nextLong() documentation states that this method will not return all possible long values:

从此随机数生成器的序列返回下一个伪随机,均匀分布的long值. nextLong 的一般约定是,一个long值是伪随机生成并返回的.方法 nextLong 由Random类实现,就像通过以下方式实现一样:

Returns the next pseudorandom, uniformly distributed long value from this random number generator's sequence. The general contract of nextLong is that one long value is pseudorandomly generated and returned. The method nextLong is implemented by class Random as if by:

public long nextLong() {
    return ((long) next(32) << 32) + next(32);
}

因为类Random使用仅具有48位的种子,所以该算法将不会返回所有可能的长值.

Because class Random uses a seed with only 48 bits, this algorithm will not return all possible long values.

例如,数字 8090327796378429294 是可生成的,但数字 8090327796378429295 不是,即使它们的唯一区别是最低有效位,并且该值本身为63位长.

For example, the number 8090327796378429294 is generatable, but the number 8090327796378429295 is not, even though their only difference is one least significant bit, and the value itself is 63 bits long.

有一种方法可以知道 nextLong()是否可以使用以下算法返回值:

There's a way to know whether or not a value can be returned by nextLong() using the following algorithm:

public class JavaRandom {
    private static final long ADD = 0xBL;
    private static final long MULT = 0x5DEECE66DL;
    private static final long TWO16 = 1L << 16;
    private static final long MASK_31 = (1L << 31) - 1;
    private static final long MASK_32 = (1L << 32) - 1;
    private static final long MASK_48 = (1L << 48) - 1;

    public static boolean canBeGeneratedByJavaRandom(long randomValue) {
        long i1 = (randomValue >> 32) & MASK_32;
        long i2 = (randomValue & MASK_32);
        if (i2 > MASK_31) {
            i1 = i1 + 1;
        }

        long front = i1 << 16;
        for (long i = 0; i < TWO16; i++) {
            long seed = front | i;
            long i22 = (((seed * MULT) + ADD) & MASK_48) >> 16;
            if (i22 == i2) {
                return true;
            }
        }

        return false;
    }
}

如何获取 nextLong()可以生成的所有值,而无需对每个可能的64位数字运行此检查?调用 nextLong()直到所有值都被收集为止,感觉不合理,而且可能会发生冲突.

How can I get all values that can be generated by nextLong() without running this check for every possible 64-bit number? Calling nextLong() until all values are collected doesn't feel reasonable as well as there can be collisions.

推荐答案

鉴于

Given that the setSeed function fully uses the lower 48 bits of the value passed in to set the seed, you can simply iterate over all seed value from 0 to (1L << 48) - 1, setSeed to each of them, then call nextLong() once for each seed.

更多信息:

  • 此答案指出,可以从2个连续的 nextInt()确定种子>值,因此没有两个不同的种子会生成相同的2个连续的 nextInt()值.
  • 文档指出, nextInt()调用 next(32),而 nextLong()获得2个连续的值next(32)值.
  • This answer points out that it's possible to determine the seed from 2 consecutive nextInt() values, therefore there are no two different seeds that generates the same 2 consecutive nextInt() values.
  • The documentation states that nextInt() calls next(32), and nextLong() gets the value of 2 consecutive next(32) values.

从以上两点来看,不同的种子值将生成不同的 nextLong()值.

From the two points above, different seed values will generate different nextLong() values.

这篇关于如何获取Random.nextLong返回的所有可能值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆