简体   繁体   English

Clojure和Java互操作:Java.math.BigInteger

[英]Clojure and Java interoperation: Java.math.BigInteger

I have a clojure code that has an output of BigInteger. 我有一个输出为BigInteger的clojure代码。

(ns com.domain.tiny
  (:gen-class
    :name com.domain.tiny
    :methods [#^{:static true} [binomial [int int] java.math.BigInteger]]))

(defn binomial
  "Calculate the binomial coefficient."
  [n k]
  (let [a (inc n)]
    (loop [b 1
           c 1]
      (if (> b k)
        c
        (recur (inc b) (* (/ (- a b) b) c))))))

(defn -binomial
  "A Java-callable wrapper around the 'binomial' function."
  [n k]
  (binomial n k))

(defn -main []
  (println (str "(binomial 5 3): " (binomial 5 3)))
  (println (str "(binomial 10042 111): " (binomial 10042 111)))
)

Executing it as a stand alone, I could get the result without an issue: 单独执行它,我可以毫无问题地得到结果:

(binomial 5 3): 10
(binomial 10042 111): 
4906838957506814494663377752836616342 ...
48178314846156008309671682804824359157818666487159757179543983405334334410427200

I could generate jar file with lein uberjar . 我可以使用lein uberjar生成jar文件。 Trying to use it from Java, I came up with this code. 试图从Java中使用它,我提出了这个代码。

import com.domain.tiny;
import java.math.BigInteger;
public class Hello
{
    public static void main(String[] args) {
        BigInteger res = tiny.binomial(5, 3);
        System.out.println("(binomial 5 3): " + res);
        res = tiny.binomial(10042, 111);
        System.out.println("(binomial 10042, 111): " + res);
    }
}

Unfortunately, I got exception. 不幸的是,我得到了例外。

Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast 
    to java.math.BigInteger
at com.domain.tiny.binomial(Unknown Source)
at Hello.main(Hello.java:11)

How can I interoperate clojure and Java for Java.Math.BigInteger? 如何为Java.Math.BigInteger互操作clojure和Java? I could use :methods [#^{:static true} [binomial [int int] double]])) and double res = tiny.binomial(10042, 111); 我可以使用:methods [#^{:static true} [binomial [int int] double]]))double res = tiny.binomial(10042, 111); but not BigInteger. 但不是BigInteger。

This is the step that I took to get the jar and execute the java. 这是我获取jar并执行java的步骤。

lein new com.domain.tiny
copy the tiny.clj in com.domain
lein deps
lein uberjar
javac -cp .:com.domain.tiny-1.0.0-SNAPSHOT-standalone.jar Hello.java
java -cp .:com.domain.tiny-1.0.0-SNAPSHOT-standalone.jar Hello

The clojure code is copied from: Calling clojure from java clojure代码复制自: 从java调用clojure

The return value should have been clojure.lang.BigInt. 返回值应该是clojure.lang.BigInt。

Clojure code Clojure代码

:methods [#^{:static true} [binomial [int int] clojure.lang.BigInt]]))
(defn binomial
  "Calculate the binomial coefficient."
  [n k]
  (let [a (inc n)]
    (loop [b 1
           c 1]
      (if (> b k)
        (bigint c) ;; <-- Without this code 
                   ;; java.lang.ClassCastException: 
                   ;; java.lang.Long cannot be cast to clojure.lang.BigInt occurs
        (recur (inc b) (* (/ (- a b) b) c))))))

Java code Java代码

import clojure.lang.BigInt;
...
BigInt res = tiny.binomial(10042, 111);
System.out.println("(binomial 10042, 111): " + res.toString());

Result 结果

java -cp .:com.domain.tiny-1.0.0-SNAPSHOT-standalone.jar Hello
>>> 
(binomial 5 3): 10
(binomial 10042 111): 49068389575068144946 … 27200

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM