在Windows计算机上播种SML/NJ的RNG

在Windows计算机上播种SML/NJ的RNG,sml,smlnj,Sml,Smlnj,如何在Windows机器上为SML/NJ的随机数生成器种子 该函数获取一对整数,并使用它们为随机数生成器设定种子。根据我对其他编程语言的经验,我希望有一种相对简单的方法,可以基于系统时钟(比如srandtimenull)来为它播种;在C中,除非我忽略了一些明显的东西,否则似乎没有任何直接的方法,至少如果你使用的是Windows 在SML中我能找到的最接近timenull的是,它返回Unix纪元时间。不幸的是,Posix结构并不是Windows下载的一部分,而且它似乎不包括任何时间的直接模拟 该结

如何在Windows机器上为SML/NJ的随机数生成器种子

该函数获取一对整数,并使用它们为随机数生成器设定种子。根据我对其他编程语言的经验,我希望有一种相对简单的方法,可以基于系统时钟(比如srandtimenull)来为它播种;在C中,除非我忽略了一些明显的东西,否则似乎没有任何直接的方法,至少如果你使用的是Windows

在SML中我能找到的最接近timenull的是,它返回Unix纪元时间。不幸的是,Posix结构并不是Windows下载的一部分,而且它似乎不包括任何时间的直接模拟

该结构确实具有确定经过的实时性的方法。我可以写一个函数,它可以进行半秒钟的无意义计算,计算所需的时间,然后找出一种方法从中提取几个整数。但是:1在大多数语言中,对于一些琐碎的东西来说,这是一项非常艰巨的工作,2更重要的是,它似乎很可能导致相同的种子在相当多的时间内被重用

我的另一个想法是,如果我可以访问Windows环境变量TIME,我就可以使用它。以下内容将时间打印到repl:

OS.Process.system "TIME/T";
但不提供对打印字符串的任何编程访问

OS.Process.getEnv "TIME";
听起来很有希望,但没有回报

如果SML/NJ中确实没有简单的解决方案,那么是否有一些选项适用于其他SML实现,如Poly/ML?

Basis库的签名具有返回当前时间的功能

val now: unit -> t
Basis库的签名具有返回当前时间的功能

val now: unit -> t

@马特自己回答了这个问题,以便携式方式读取系统时钟。为了补充他的答案,这里有一个种子函数。作为一个技术问题,自1970年以来,对于SML/NJ 31位整数来说,经过的秒数太大。我当然可以使用大整数,但一个简单的解决方案似乎是在转换为整数之前减少14.8亿秒,并使用时间的小数部分来获得第二个整数种子参数:

fun seed () = 
    let
        val r = Time.toReal(Time.now()) - 1.48e9
        val f = Real.realFloor(r)
        val d = r - f
        val i = Real.floor(f)
        val j = Real.floor(1000.0*d)
    in
        Random.rand(i,j)
    end;
几乎可以肯定的是,有一种更具原则性的方法可以做到这一点,但上述方法是可行的:

- val s = seed ();
val s =
  RND
    {borrow=ref false,congx=ref 0wx4B7CD4CA,index=ref 0,
     vals=[|0wx40E9888B,0wx6F1B97FD,0wx4011C479,0wx2012F528,0wx3CDC0237,
           0wx7C36E91D,0wx5361B64D,0wx4B61A297,0wx61823821,0wx7C6CD6BD,
           0wx1683CA4D,0wx670A75AF,...|]} : Random.rand
- Random.randRange(1,100) s;
val it = 35 : int
- val s = seed ();
val s =
  RND
    {borrow=ref false,congx=ref 0wx512EBCFC,index=ref 0,
     vals=[|0wx456E115A,0wx27817499,0wx46A6BE48,0wx2C79BB3,0wx3FF47B4D,
           0wx5B48FC93,0wx53C3647F,0wx32E40F5A,0wx157AB4C8,0wx16E750D,
           0wx78BD3EA3,0wx7885CA23,...|]} : Random.rand
- Random.randRange(1,100) s;
val it = 73 : int

不太令人兴奋,但连续的种子仅隔几秒钟就产生了不同的输出,正如预期的那样。

@matt自己回答了这个问题,以便携式方式获取系统时钟读数。为了补充他的答案,这里有一个种子函数。作为一个技术问题,自1970年以来,对于SML/NJ 31位整数来说,经过的秒数太大。我当然可以使用大整数,但一个简单的解决方案似乎是在转换为整数之前减少14.8亿秒,并使用时间的小数部分来获得第二个整数种子参数:

fun seed () = 
    let
        val r = Time.toReal(Time.now()) - 1.48e9
        val f = Real.realFloor(r)
        val d = r - f
        val i = Real.floor(f)
        val j = Real.floor(1000.0*d)
    in
        Random.rand(i,j)
    end;
几乎可以肯定的是,有一种更具原则性的方法可以做到这一点,但上述方法是可行的:

- val s = seed ();
val s =
  RND
    {borrow=ref false,congx=ref 0wx4B7CD4CA,index=ref 0,
     vals=[|0wx40E9888B,0wx6F1B97FD,0wx4011C479,0wx2012F528,0wx3CDC0237,
           0wx7C36E91D,0wx5361B64D,0wx4B61A297,0wx61823821,0wx7C6CD6BD,
           0wx1683CA4D,0wx670A75AF,...|]} : Random.rand
- Random.randRange(1,100) s;
val it = 35 : int
- val s = seed ();
val s =
  RND
    {borrow=ref false,congx=ref 0wx512EBCFC,index=ref 0,
     vals=[|0wx456E115A,0wx27817499,0wx46A6BE48,0wx2C79BB3,0wx3FF47B4D,
           0wx5B48FC93,0wx53C3647F,0wx32E40F5A,0wx157AB4C8,0wx16E750D,
           0wx78BD3EA3,0wx7885CA23,...|]} : Random.rand
- Random.randRange(1,100) s;
val it = 73 : int

这不是很令人兴奋,但连续的种子仅隔几秒钟就产生了不同的结果,正如预期的那样。

这应该是可行的。奇怪的是,我不止一次看了《时间》,却忽略了这一点。我得到的印象是,时间是用来解析计时器返回的值的,但它本身并不包含时钟信息。我在正常的basis文档中也遗漏了它,它将更新答案以反映出它是一个应该工作的标准函数。奇怪的是,我不止一次看了《时间》,却忽略了这一点。我得到的印象是,时间是用来解析计时器返回的值的,但它本身并不包含时钟信息。我在正常的basis文档中也遗漏了它,将更新答案以反映其标准函数