Clojure BigInt не является Java BigInteger

Я пытаюсь использовать BigDecimals в Clojure для моделирования (при необходимости) чисел произвольной точности. У меня есть странная ошибка, когда я пытаюсь создать экземпляр 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

Проблема здесь в том, что большое целое число clojure НЕ является объектом java.math.BigInteger. Даже (bigint x) не работает:

user=> (doc bigint)
-------------------------
clojure.core/bigint
([x])
  Coerce to BigInt
nil

И, кстати, конструктор BigInteger напрямую не принимает числовые значения. Я знаю, что мог бы также сделать что-то вроде:

user=> (BigDecimal. (BigInteger. (.toByteArray (.unscaledValue 1.31M))) (.scale 1.31M))
1.31M

Мой вопрос: есть ли более идиоматический способ непосредственного управления объектами BigInteger из Clojure? Или я застрял, чтобы обернуть все в пользовательскую библиотеку, например:

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

Заранее спасибо за помощь!

ОБНОВЛЕНИЕ: I НУЖЕНBigInteger для целей сериализации: Моя идея состоит в том, чтобы хранить BigDecimal в виде массива байтов и целого числа. Моя проблема в том, что в Clojure, если я хочу, я не могу передать результат .unscaledValue туда и обратно' потому что Clojure не обрабатывает BigInteger, созданный из Integers (как и Java, что имеет значение):

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

Вызов .toString на номере бесполезен для семантики сериализации (и более подвержен ошибкам). Я хотел бы знать, есть ли в Clojure идиоматический способ написать что-то вроде:

user=> (bigdec 131N 2)

Нет .movePointLeft (создание двух разных объектов без преимуществ), нет .toString (у меня есть число, я нанизываю его, а затем создаю BigInteger, другое число, из него?), нет медленного и косвенного метода: просто просто BigInteger и масштабное значение.

Vinz

7
задан Vincenzo Maggio 18 June 2016 в 13:40
поделиться