Unchecked operators perform Clojure arithmetic without integer overflow checks. Use them when wraparound is intentional, such as in hashing, rather than when an overflowing result would be an error. There are two families: general unchecked operators and operators ending in -int. section 5.13 section 5.14
The families differ in arity and result type:
- unchecked-add, unchecked-subtract, and unchecked-multiply take exactly two numeric arguments; unchecked-inc, unchecked-dec, and unchecked-negate take one. Their result type follows numeric type promotion. section 5.13
- The -int family casts arguments to int and returns an int result. Add, subtract, multiply, divide, and remainder take two arguments; inc, dec, and negate take one. Inputs must fit the int range, and results can overflow its 32 signed bits. section 5.14
Same operation, different result type
(unchecked-add 2.0 1) ;=> 3.0 (unchecked-add-int 2.0 1) ;=> 3 (type (unchecked-add-int 2.0 1)) ;=> java.lang.Integer The -int suffix selects int arithmetic instead of preserving the floating-point result type. section 5.14
Wraparound at a long boundary
(unchecked-inc (long (Math/pow 2 63))) ;=> -9223372036854775808 Incrementing the largest signed long wraps to the other end of the range. section 5.13
(defn scramble [^long x ^long y] ; #1
(unchecked-add (unchecked-multiply 31 x) y)) ; #2
(defn hash-str [s] ; #3
(let [large-prime 1125899906842597] ; #4
(reduce scramble large-prime (map int s)))) ; #5
(hash-str "couple words") ; #6
;; 1664082230529263278
(hash-str "even longer sentences")
;; -7674745620208396614
A string-hashing function combines multiplication and addition with unchecked operators, putting intentional overflow to work. section 5.13
Choose the -int family when the calculation is deliberately int-based, as with integer coordinates in an image array. Choose the general family when the operands’ promoted type is wanted. Neither family provides overflow checking. section 5.13 section 5.14
