【问题标题】:The clojure way to generate a random long numberclojure 生成随机长数的方式
【发布时间】:2016-02-07 04:27:29
【问题描述】:

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

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

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

    你可以做类似的事情

    (long (rand n)))

    【讨论】:

      【解决方案2】:

      Clojure 的 randrand-int 使用 java.util.Random 作为底层随机数生成器。如果您的应用程序严重依赖随机数,您可能需要考虑使用用 Java 编写的 higher-quality random number generator,例如 MersenneTwisterFast。这有一个nextLong() 方法,并且在 Clojure 中很容易使用。 Java 的标准类SecureRandom 也可能值得考虑;它的设计目的与 Mersenne Twister 不同。还有其他不错的 Java 随机数生成器可用。取决于您使用随机数的目的。对于偶尔使用随机数,java.util.Random 可能就可以了。其他人在 cmets 中提到了其他选项。

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

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

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

      然后将 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))
      

      【讨论】:

      • 替代随机源可能是一个好主意,具体取决于 OP 的应用程序,但肯定没有必要仅仅获得long。使用j.u.Random中的对应方法即可
      • 从 Java 8 开始,还有ThreadLocalRandom,它的方法选择范围更广,不需要创建实例:(.nextLong (java.util.concurrent.ThreadLocalRandom/current) 528029243649)
      • 谢谢@glts。我不知道ThreadLocalRandom。 (由于我不熟悉它,我想我只会让您的评论成为信息来源,而不是不断地在我的答案中添加选项。不过,我会添加一个指向 cmets 的注释。)
      猜你喜欢
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 2012-01-26
      • 1970-01-01
      相关资源
      最近更新 更多