Clojure BigInt不是Java BigInteger

Vin*_*gio 7 clojure biginteger bigdecimal

我正在尝试在Clojure中使用BigDecimals来模拟(如果需要)任意精度数字.当我尝试从未缩放的值和比例因子实例化BigDecimal时,我有一个奇怪的错误:

user=> 1.31M
1.31M (OK)
user=> (class 1.31M)
java.math.BigDecimal (OK)
user=> (.unscaledValue 1.31M)
131 (OK)
user=> (.scale 1.31M)
2 (OK)
user=> (.movePointLeft (BigDecimal. 131) 2)
1.31M (OK)
user=> (BigDecimal. (BigInteger. "131") 2)
1.31M
user=> (BigDecimal. 131N 2) (WRONG!!!)
IllegalArgumentException No matching ctor found for class java.math.BigDecimal  clojure.lang.Reflector.invokeConstructor (Reflector.java:183)
user=> (BigDecimal. (BigInteger. "131") 2)
1.31M
Run Code Online (Sandbox Code Playgroud)

这里的问题是clojure大整数不是java.math.BigInteger对象.偶数(bigint x)不起作用:

user=> (doc bigint)
-------------------------
clojure.core/bigint
([x])
  Coerce to BigInt
nil
Run Code Online (Sandbox Code Playgroud)

顺便说一句,BigInteger构造函数不直接接受数值.我知道我也可以这样做:

user=> (BigDecimal. (BigInteger. (.toByteArray (.unscaledValue 1.31M))) (.scale 1.31M))
1.31M
Run Code Online (Sandbox Code Playgroud)

我的问题是:是否有更惯用的方法直接管理来自Clojure的BigInteger对象?或者我坚持将所有内容都包装在自定义库中,例如:

user=> (defn my-bigint [x] (BigInteger. (.toString x)))
#'user/my-bigint
user=> (my-bigint 131)
131
user=> (BigDecimal. (my-bigint 131) 2)
1.31M
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

更新:我需要 BigInteger进行序列化:我的想法是将BigDecimal存储为字节数组和整数.我的问题是在Clojure中,如果我想要,我不能来回传递.unscaledValue的结果'因为Clojure不处理从Integers创建的BigInteger(Java也没有,因为它重要):

user=> (BigInteger. 3)
IllegalArgumentException No matching ctor found for class java.math.BigInteger  clojure.lang.Reflector.invokeConstructor (Reflector.java:183)
Run Code Online (Sandbox Code Playgroud)

对数字的.toString调用对于序列化的语义是不可用的(并且更容易出错).我想知道在Clojure中是否有一种惯用的方法可以写出:

user=> (bigdec 131N 2)
Run Code Online (Sandbox Code Playgroud)

没有.movePointLeft(创建两个没有好处的不同对象),没有.toString(我有一个数字,我将其字符串化,然后创建一个BigInteger,另一个数字,来自它?),没有慢速和间接方法:只是简单的BigInteger和规模值.

Vinz

Nie*_*lsK 8

=> (type (.unscaledValue 1.31M))
java.math.BigInteger

=> (type (biginteger 131))
java.math.BigInteger

=> (BigDecimal. (biginteger 131) 2)
1.31M
Run Code Online (Sandbox Code Playgroud)