Прецеденты для BigInt и BigInteger в Clojure
Я ищу руководство по использованию Clojure BigInt и Java BigInteger в Clojure. Я считаю, что основной причиной использования BigInt является использование таких операторов, как +
и =
, которые должны быть доступны через методы экземпляра Java .add
и .equals
, для пример. Но есть несколько операторов, таких как isProbablePrime
, которые я могу получить только из BigInteger.
Кажется довольно легко перейти от BigInt к BigInteger или наоборот, но наличие обоих делает случаи использования непонятными для меня. Моя реакция на коленный рефлекс заключается в том, чтобы придерживаться BigInteger в отсутствие четких критериев, поскольку некоторые из предложенных применений, похоже, не работают. Из clojuredocs здесь:
user=> (def x (bigint 97))
user=> (.isProbablePrime x 1)
IllegalArgumentException No matching method found: isProbablePrime for class
clojure.lang.BigInt clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)
Ответы
Ответ 1
В "Clojure Программирование" C. Emerick et. al., p.428, есть тема в боковой панели: "Почему Clojure имеет свой собственный класс BigInt, когда Java уже предоставляет один в BigInteger?"
Они отмечают две причины, чтобы предпочесть BigInt
на Java BigInteger
. Во-первых, последняя реализация .hashCode
несовместима с реализацией Long
(одно и то же число, выраженное в каждом типе, дает другое значение хэш-функции). Обычно это не то, что вы хотите, сравнивая эквивалентные значения, например. хэш-карты.
Другая причина заключается в том, что BigInt
оптимизированы для использования примитивных типов, когда это возможно, поэтому производительность должна быть лучше для многих случаев.
Я бы использовал числовые типы Clojure, если у вас нет веских оснований для этого (ваше использование .isProbablePrime
предполагает, что у вас может быть достаточно хорошая причина).