用于生成随机长数的clojure方式

dan*_*nny 5 clojure

使用Clojure,如何生成随机长数?我知道Clojure有一个rand-int函数,但它只适用于整数.如果给定的数字很长,我得到了这个repl错误:

IllegalArgumentException Value out of range for int: 528029243649 clojure.lang.RT.intCast (RT.java:1205)

Tim*_*ley 8

如果你看一下rand-int的来源

(defn rand-int
  "Returns a random integer between 0 (inclusive) and n (exclusive)."
  [n] (int (rand n)))
Run Code Online (Sandbox Code Playgroud)

你可以做类似的事情

(long (rand n)))


Mar*_*ars 7

Clojure的randrand-int使用java.util.Random作为底层的随机数发生器.如果您的应用程序严重依赖于随机数,您可能需要考虑使用用Java编写的更高质量的随机数生成器,例如MersenneTwisterFast.这有一个nextLong()方法,它很容易在Clojure中使用.Java的标准类SecureRandom也值得考虑; 它的设计目的不同于Mersenne Twister.还有其他优秀的Java随机数生成器.取决于您使用的随机数.偶尔使用随机数,java.util.Random可能就好了.其他人在评论中提到了其他选项.

我将描述使用MersenneTwisterFast.使用我提到的其他类基本上是相同的,但没有初始步骤.

使用Leiningen,将这样的内容添加到project.clj:

  :java-source-paths ["src/java"]
Run Code Online (Sandbox Code Playgroud)

然后将MersenneTwisterFast.java的Java源代码放在src/java/ec/util中.然后你可以这样做:

(ns my.namespace
  (:import [ec.util MersenneTwisterFast]))

(def rng (MersenneTwisterFast. 42)) ; Specify a different seed, e.g. from system time.
(defn next-long [] (.nextLong rng))
Run Code Online (Sandbox Code Playgroud)

  • 从Java 8开始,还有[`ThreadLocalRandom`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadLocalRandom.html),它有更广泛的方法选择,并且没有不需要创建一个实例:`(.nextLong(java.util.concurrent.ThreadLocalRandom/current)528029243649)`. (3认同)