Working With Clojure Arithmetic Functions

Continuing the exploration of the Clojure API, here are some of the arithmetic functions.

 

;; Let's define a field with one less that the max value of a long
user=> (def long-max-minus-1 (- Long/MAX_VALUE 1) )
#'user/long-max-minus-1
user=> long-max-minus-1
9223372036854775806
;; +' will auto-promote longs, + will not
user=> (+' long-max-minus-1 1)
9223372036854775807
user=> (+ long-max-minus-1 1)
9223372036854775807
user=> (+ long-max-minus-1 2)

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
user=> (+' long-max-minus-1 2)
9223372036854775808N
user=> (+' long-max-minus-1 2)
9223372036854775808N
user=> (+' long-max-minus-1 3)
9223372036854775809N
user=> (+' long-max-minus-1 4)
9223372036854775810N
user=> (+' long-max-minus-1 5)
9223372036854775811N

;; Let's do the same with inc and inc'
user=> (inc long-max-minus-1)
9223372036854775807
user=> (inc (inc long-max-minus-1))

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
user=> (inc' (inc long-max-minus-1))
9223372036854775808N

;; other than that, + and +' behave the same
;; (as long as you are not near 9.22 times 10 to the 18th)
user=> (+ 1 2 3 4 5)
15
user=> (+' 1 2 3 4 5)
15

;; Let's do the same with the minimum value of a long
user=> (def long-min-plus-1 (+ Long/MIN_VALUE 1))
#'user/long-min-plus-1
user=> long-min-plus-1
-9223372036854775807
user=> (- long-min-plus-1 1)
-9223372036854775808
user=> (- long-min-plus-1 2)

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
user=> (-' long-min-plus-1 1)
-9223372036854775808
user=> (-' long-min-plus-1 2)
-9223372036854775809N
user=> (-' long-min-plus-1 3)
-9223372036854775810N
user=> (-' long-min-plus-1 4)
-9223372036854775811N
user=> (dec long-min-plus-1)
-9223372036854775808
user=> (dec (dec long-min-plus-1))

ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)
user=> (dec' (dec long-min-plus-1))
-9223372036854775809N
;; other than that, no difference
user=> (- 1 2 3 4 5)
-13
user=> (-' 1 2 3 4 5)
-13

;; division
user=> (/ 3 2)
3/2
;; we can add multiple types of numbers
user=> (+ 5 (/ 3 2))
13/2
user=> (- 5 (/ 3 2))
7/2

user=> (inc (/ 3 2))
5/2
user=> (inc' (/ 3 2))
5/2
user=> (dec (/ 3 2))
1/2
user=> (dec' (/ 3 2))
1/2

user=> (+ 1 2.3)
3.3
user=> (+ 3 9.876)
12.876
;; - gives us very precise numbers
user=> (- 1 2.3)
-1.2999999999999998
user=> (- 2 2.3)
-0.2999999999999998
user=> (-' 2 2.3)
-0.2999999999999998
user=> (+ 2 2.3)
4.3
user=> (inc 2.3)
3.3
user=> (dec 2.3)
1.2999999999999998
user=> (+ 3 2.0)
5.0
user=> (- 3 2.0)
1.0
user=> (+ 3 2.01)
5.01
user=> (- 3 2.01)
0.9900000000000002
user=> (+ 3 2.1)
5.1
user=> (- 3 2.1)
0.8999999999999999
user=> (* 2 3)
6
user=> (* 2 3 4)
24
user=> (/ 2 3)
2/3
;; +, -, * and / can all handle multiple numbers of args
user=> (/ 2 3 4)
1/6
user=> (* 2 3 4 5)
120
user=> (/ 2 3 4 5)
1/30
user=> (/ 12 3 4 5)
1/5
;; It is easier to understand why division gives very precise numbers
user=> (/ 12 3 4 5.3)
0.18867924528301888
user=> (* 2 3 4 5.3)
127.19999999999999
user=> (* 2.3 4 (/ 5 2))
23.0
user=> (* 2.3 4 (/ 5 3))
15.333333333333336
;; note to self: Look into octal numbers
user=> (* 2 010)
16
;; still no way to avoid the inevitable
user=> (/ 2 0)

ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:158)

You’re welcome.