Какие математические функции заканчиваются апострофом в Clojure?

Есть некоторые математические функции, которые заканчиваются апострофом, например: +', *' и -'.

В чем разница между неапострофными и апострофными?

Ответ 1

Они являются "автоматическими" версиями нормальных математических функций.

user> (* Long/MAX_VALUE 2)
ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
user> (*' Long/MAX_VALUE 2)
18446744073709551614N

Они возвращают более крупный тип данных, чем вход, если выход становится слишком большим. Раньше это было поведение по умолчанию в начале Clojure, а затем оно было изменено, чтобы генерировать исключение, если вывод математической операции переполнил его тип данных. Это улучшило числовые характеристики и, как правило, помогло найти ошибки. В течение пяти или около того лет с тех пор удивительно мало людей жаловались на это изменение, нарушающее что-либо. Было решено сохранить поведение исключения исключения при переполнении, потому что это почти всегда ошибка.

На практике большую часть времени вы узнаете, когда вам понадобится использовать BigIntegers и BigDecimals, и вы можете использовать обычные функции с этими типами данных.

user> (* Long/MAX_VALUE 2N)
18446744073709551614N

В этом примере я использовал обычную функцию * и передал ей аргумент типа BigInteger (что означает N in 2N для clojure -reader)

Есть несколько случаев, когда вам действительно нужно работать с любым размером, не зная заранее, и эти функции пригодится. Пока что большинство из этих примеров для меня являются факториальными примерами в StackOverflow.

Если вы действительно хотите, чтобы ваша математическая операция переполнена, вы можете использовать явно небезопасные математические функции:

user> (unchecked-add Long/MAX_VALUE 2)
-9223372036854775807