2016-02-07 71 views
4

隨着Clojure,我該如何產生一個隨機的長號碼?我知道Clojure有一個rand-int函數,但它只適用於整數。如果給定的數字是漫長的,我得到這個REPL錯誤:如果你看一看蘭特-INT源clojure的方式來產生一個隨機的長號碼

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

你可以做類似的事情

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

回答

8

(long (rand n)))

7

Clojure的randrand-int使用java.util.Random作爲潛在的隨機數發生器。如果您的應用程序嚴重依賴於隨機數,則可能需要考慮使用用Java編寫的higher-quality random number generator,如MersenneTwisterFast。這有一個nextLong()方法,並且從Clojure使用起來非常簡單。 Java的標準類SecureRandom也許值得考慮;它的設計目的不同於Mersenne Twister。還有其他好的Java隨機數生成器可用。取決於你使用的隨機數字。偶爾使用隨機數字,java.util.Random可能會很好。其他人在評論中提到了其他選項。

我將描述使用MersenneTwisterFast。使用我提到的其他類將基本相同,但沒有初始步驟。

隨着Leiningen,加入這樣的事情project.clj:

:java-source-paths ["src/java"] 

,然後把Java源代碼的MersenneTwisterFast.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)) 
+0

另一種隨機性源可以是依賴於OP的應用程序是個好主意,但它肯定是沒有必要只是爲了得到一個'long'。只需使用[j.u.Random]中的相應方法(https://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextLong()) – amalloy

+0

您是對的@amalloy。我會更新答案。 – Mars

+3

自Java 8以來,還有['ThreadLocalRandom'](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadLocalRandom.html),它具有更廣泛的方法選擇和不需要創建實例:'(.nextLong(java.util.concurrent.ThreadLocalRandom/current)528029243649)'。 – glts