Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 日历类和生成数字时出错_Java_Random_Time - Fatal编程技术网

Java 日历类和生成数字时出错

Java 日历类和生成数字时出错,java,random,time,Java,Random,Time,我正在尝试使用给定的日期生成随机数,以便在Java中创建良好的伪随机数。我决定使用日历类并计算一天中的毫秒数。这在某种程度上是有效的,但我只能在启动程序时得到一个不同的随机值。在程序中再运行几次就会得到相同的数字。我正在使用Thread.sleep()来确保时间上有实际差异,但我仍然得到相同的数字。 这是我正在调用的方法(从另一个类) 这是我的主要方法 public static void main(String[] args) throws InterruptedException {

我正在尝试使用给定的日期生成随机数,以便在Java中创建良好的伪随机数。我决定使用
日历
类并计算一天中的毫秒数。这在某种程度上是有效的,但我只能在启动程序时得到一个不同的随机值。在程序中再运行几次就会得到相同的数字。我正在使用
Thread.sleep()
来确保时间上有实际差异,但我仍然得到相同的数字。 这是我正在调用的方法(从另一个类)

这是我的主要方法

public static void main(String[] args) throws InterruptedException
{
    Seed key = new Seed();
    for (int x = 0; x <=10; x++)
    {
        Thread.sleep(200);
        System.out.println(key.genRNG());
    }
}

似乎您每次都将
mask
设置为相同的值,并且每次将
seed
设置为相同的值,因此
seed&mask
每次生成相同的值。
Calendar
对象在实例化后不会自动更改其值-换句话说,它会保留您构建它时获得的时间(通常是构建它时的时间),直到您显式更改它为止。因此,一个建议是在每次调用
genRNG()
时重新初始化
cal

在这里,我将
cal
更改为局部变量:

    long mask = 0xFFFF000000000000L;
    long randomValue = seed & mask;
    Calendar cal = Calendar.getInstance();
    seed = 0x5D588B656C078965L * cal.get(Calendar.MILLISECOND) + 0x0000000000269EC3;
    return randomValue;
现在我可以得到如下输出:

0
8430738502437568512
-2453898846963499008
2916080758722396160
3291568377654411264
-1326873040214032384
-951385421282017280
1212312724692795392
-3406128693175648256
-1298444067566256128
-5916885485434699776
初始0来自未初始化的
种子
。我想这在你的代码中不是问题

不过我觉得你还没到
Calendar.get(Calendar.millis秒)
总是返回一个介于0到999之间的值,因此您最多可以得到1000个不同的“随机”值。在
long
中存储不多。您可能会得到更多信息,例如:

    seed = 0x5D588B656C078965L * System.currentTimeMillis() + 0x0000000000269EC3;
如果出于某种原因,您需要当前时间的对象,而不仅仅是从
System.currentTimeMillis()
获得的
long
,如果您可以使用Java 8,我建议您使用
Instant.now().toEpochMilli()
。它为您提供了相同的
long
值,但
Instant.now()
为您提供了一个表示当前时间的对象,非常类似于
Calendar.getInstance()
,只是如果您想将其用于其他用途,它更现代、更通用

另一个问题是,由于掩码,您的值在二进制表示中总是以48个零结尾(很容易看到所有值都是偶数)。也许这是设计好的


另外,我认为有一个原因可以解释为什么您不只是使用
java.util.Random

,而是在返回
randomValue
的同时更改
seed
变量值,你没有改变
cal
。随机值是由种子组成的。你说Jon是什么意思?看来你每次都将
mask
设置为相同的值,每次将
Seed
设置为相同的值,所以
Seed&mask
每次都会产生相同的值。哇,这是一个非常好的答案!非常感谢你们,我想投票,但我没有足够的声誉我用日历,因为我不知道任何其他方法来跟踪时间,是的,我正在尝试做我自己的版本的线性全等随机数生成器。
0
8430738502437568512
-2453898846963499008
2916080758722396160
3291568377654411264
-1326873040214032384
-951385421282017280
1212312724692795392
-3406128693175648256
-1298444067566256128
-5916885485434699776
    seed = 0x5D588B656C078965L * System.currentTimeMillis() + 0x0000000000269EC3;