diff src/clojure/test_clojure/numbers.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/test_clojure/numbers.clj	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,444 @@
     1.4 +;   Copyright (c) Rich Hickey. All rights reserved.
     1.5 +;   The use and distribution terms for this software are covered by the
     1.6 +;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
     1.7 +;   which can be found in the file epl-v10.html at the root of this distribution.
     1.8 +;   By using this software in any fashion, you are agreeing to be bound by
     1.9 +;   the terms of this license.
    1.10 +;   You must not remove this notice, or any other, from this software.
    1.11 +
    1.12 +; Author: Stephen C. Gilardi
    1.13 +;;  scgilardi (gmail)
    1.14 +;;  Created 30 October 2008
    1.15 +;;
    1.16 +
    1.17 +(ns clojure.test-clojure.numbers
    1.18 +  (:use clojure.test))
    1.19 +
    1.20 +
    1.21 +; TODO:
    1.22 +; ==
    1.23 +; and more...
    1.24 +
    1.25 +
    1.26 +;; *** Types ***
    1.27 +
    1.28 +(deftest Coerced-Byte
    1.29 +  (let [v (byte 3)]
    1.30 +    (are [x] (true? x)
    1.31 +     (instance? Byte v)
    1.32 +     (number? v)
    1.33 +     (integer? v)
    1.34 +     (rational? v))))
    1.35 +
    1.36 +(deftest Coerced-Short
    1.37 +  (let [v (short 3)]
    1.38 +    (are [x] (true? x)
    1.39 +     (instance? Short v)
    1.40 +     (number? v)
    1.41 +     (integer? v)
    1.42 +     (rational? v))))
    1.43 +
    1.44 +(deftest Coerced-Integer
    1.45 +  (let [v (int 3)]
    1.46 +    (are [x] (true? x)
    1.47 +     (instance? Integer v)
    1.48 +     (number? v)
    1.49 +     (integer? v)
    1.50 +     (rational? v))))
    1.51 +
    1.52 +(deftest Coerced-Long
    1.53 +  (let [v (long 3)]
    1.54 +    (are [x] (true? x)
    1.55 +     (instance? Long v)
    1.56 +     (number? v)
    1.57 +     (integer? v)
    1.58 +     (rational? v))))
    1.59 +
    1.60 +(deftest Coerced-BigInteger
    1.61 +  (let [v (bigint 3)]
    1.62 +    (are [x] (true? x)
    1.63 +     (instance? BigInteger v)
    1.64 +     (number? v)
    1.65 +     (integer? v)
    1.66 +     (rational? v))))
    1.67 +
    1.68 +(deftest Coerced-Float
    1.69 +  (let [v (float 3)]
    1.70 +    (are [x] (true? x)
    1.71 +     (instance? Float v)
    1.72 +     (number? v)
    1.73 +     (float? v))))
    1.74 +
    1.75 +(deftest Coerced-Double
    1.76 +  (let [v (double 3)]
    1.77 +    (are [x] (true? x)
    1.78 +     (instance? Double v)
    1.79 +     (number? v)
    1.80 +     (float? v))))
    1.81 +
    1.82 +(deftest Coerced-BigDecimal
    1.83 +  (let [v (bigdec 3)]
    1.84 +    (are [x] (true? x)
    1.85 +     (instance? BigDecimal v)
    1.86 +     (number? v)
    1.87 +     (decimal? v)
    1.88 +     (not (float? v)))))
    1.89 +
    1.90 +
    1.91 +;; *** Functions ***
    1.92 +
    1.93 +(defonce DELTA 1e-12)
    1.94 +
    1.95 +(deftest test-add
    1.96 +  (are [x y] (= x y)
    1.97 +      (+) 0
    1.98 +      (+ 1) 1
    1.99 +      (+ 1 2) 3
   1.100 +      (+ 1 2 3) 6
   1.101 +
   1.102 +      (+ -1) -1
   1.103 +      (+ -1 -2) -3
   1.104 +      (+ -1 +2 -3) -2
   1.105 +
   1.106 +      (+ 1 -1) 0
   1.107 +      (+ -1 1) 0
   1.108 +
   1.109 +      (+ 2/3) 2/3
   1.110 +      (+ 2/3 1) 5/3
   1.111 +      (+ 2/3 1/3) 1 )
   1.112 +
   1.113 +  (are [x y] (< (- x y) DELTA)
   1.114 +      (+ 1.2) 1.2
   1.115 +      (+ 1.1 2.4) 3.5
   1.116 +      (+ 1.1 2.2 3.3) 6.6 )
   1.117 +
   1.118 +  (is (> (+ Integer/MAX_VALUE 10) Integer/MAX_VALUE))  ; no overflow
   1.119 +  (is (thrown? ClassCastException (+ "ab" "cd"))) )    ; no string concatenation
   1.120 +
   1.121 +
   1.122 +(deftest test-subtract
   1.123 +  (is (thrown? IllegalArgumentException (-)))
   1.124 +  (are [x y] (= x y)
   1.125 +      (- 1) -1
   1.126 +      (- 1 2) -1
   1.127 +      (- 1 2 3) -4
   1.128 +
   1.129 +      (- -2) 2
   1.130 +      (- 1 -2) 3
   1.131 +      (- 1 -2 -3) 6
   1.132 +
   1.133 +      (- 1 1) 0
   1.134 +      (- -1 -1) 0
   1.135 +
   1.136 +      (- 2/3) -2/3
   1.137 +      (- 2/3 1) -1/3
   1.138 +      (- 2/3 1/3) 1/3 )
   1.139 +
   1.140 +  (are [x y] (< (- x y) DELTA)
   1.141 +      (- 1.2) -1.2
   1.142 +      (- 2.2 1.1) 1.1
   1.143 +      (- 6.6 2.2 1.1) 3.3 )
   1.144 +
   1.145 +  (is (< (- Integer/MIN_VALUE 10) Integer/MIN_VALUE)) )  ; no underflow
   1.146 +
   1.147 +
   1.148 +(deftest test-multiply
   1.149 +  (are [x y] (= x y)
   1.150 +      (*) 1
   1.151 +      (* 2) 2
   1.152 +      (* 2 3) 6
   1.153 +      (* 2 3 4) 24
   1.154 +
   1.155 +      (* -2) -2
   1.156 +      (* 2 -3) -6
   1.157 +      (* 2 -3 -1) 6
   1.158 +
   1.159 +      (* 1/2) 1/2
   1.160 +      (* 1/2 1/3) 1/6
   1.161 +      (* 1/2 1/3 -1/4) -1/24 )
   1.162 +
   1.163 +  (are [x y] (< (- x y) DELTA)
   1.164 +      (* 1.2) 1.2
   1.165 +      (* 2.0 1.2) 2.4
   1.166 +      (* 3.5 2.0 1.2) 8.4 )
   1.167 +
   1.168 +  (is (> (* 3 (int (/ Integer/MAX_VALUE 2.0))) Integer/MAX_VALUE)) )  ; no overflow
   1.169 +
   1.170 +(deftest test-ratios-simplify-to-ints-where-appropriate
   1.171 +  (testing "negative denominator (assembla #275)"
   1.172 +    (is (integer? (/ 1 -1/2)))
   1.173 +    (is (integer? (/ 0 -1/2)))))
   1.174 +
   1.175 +(deftest test-divide
   1.176 +  (are [x y] (= x y)
   1.177 +      (/ 1) 1
   1.178 +      (/ 2) 1/2
   1.179 +      (/ 3 2) 3/2
   1.180 +      (/ 4 2) 2
   1.181 +      (/ 24 3 2) 4
   1.182 +      (/ 24 3 2 -1) -4
   1.183 +
   1.184 +      (/ -1) -1
   1.185 +      (/ -2) -1/2
   1.186 +      (/ -3 -2) 3/2
   1.187 +      (/ -4 -2) 2
   1.188 +      (/ -4 2) -2 )
   1.189 +
   1.190 +  (are [x y] (< (- x y) DELTA)
   1.191 +      (/ 4.5 3) 1.5
   1.192 +      (/ 4.5 3.0 3.0) 0.5 )
   1.193 +
   1.194 +  (is (thrown? ArithmeticException (/ 0)))
   1.195 +  (is (thrown? ArithmeticException (/ 2 0)))
   1.196 +  (is (thrown? IllegalArgumentException (/))) )
   1.197 +
   1.198 +
   1.199 +;; mod
   1.200 +;; http://en.wikipedia.org/wiki/Modulo_operation
   1.201 +;; http://mathforum.org/library/drmath/view/52343.html
   1.202 +;;
   1.203 +;; is mod correct?
   1.204 +;; http://groups.google.com/group/clojure/browse_frm/thread/2a0ee4d248f3d131#
   1.205 +;;
   1.206 +;; Issue 23: mod (modulo) operator
   1.207 +;; http://code.google.com/p/clojure/issues/detail?id=23
   1.208 +
   1.209 +(deftest test-mod
   1.210 +  ; wrong number of args
   1.211 +  (is (thrown? IllegalArgumentException (mod)))
   1.212 +  (is (thrown? IllegalArgumentException (mod 1)))
   1.213 +  (is (thrown? IllegalArgumentException (mod 3 2 1)))
   1.214 +
   1.215 +  ; divide by zero
   1.216 +  (is (thrown? ArithmeticException (mod 9 0)))
   1.217 +  (is (thrown? ArithmeticException (mod 0 0)))
   1.218 +
   1.219 +  (are [x y] (= x y)
   1.220 +    (mod 4 2) 0
   1.221 +    (mod 3 2) 1
   1.222 +    (mod 6 4) 2
   1.223 +    (mod 0 5) 0
   1.224 +
   1.225 +    (mod 2 1/2) 0
   1.226 +    (mod 2/3 1/2) 1/6
   1.227 +    (mod 1 2/3) 1/3
   1.228 +
   1.229 +    (mod 4.0 2.0) 0.0
   1.230 +    (mod 4.5 2.0) 0.5
   1.231 +
   1.232 +    ; |num| > |div|, num != k * div
   1.233 +    (mod 42 5) 2      ; (42 / 5) * 5 + (42 mod 5)        = 8 * 5 + 2        = 42
   1.234 +    (mod 42 -5) -3    ; (42 / -5) * (-5) + (42 mod -5)   = -9 * (-5) + (-3) = 42
   1.235 +    (mod -42 5) 3     ; (-42 / 5) * 5 + (-42 mod 5)      = -9 * 5 + 3       = -42
   1.236 +    (mod -42 -5) -2   ; (-42 / -5) * (-5) + (-42 mod -5) = 8 * (-5) + (-2)  = -42
   1.237 +
   1.238 +    ; |num| > |div|, num = k * div
   1.239 +    (mod 9 3) 0       ; (9 / 3) * 3 + (9 mod 3) = 3 * 3 + 0 = 9
   1.240 +    (mod 9 -3) 0
   1.241 +    (mod -9 3) 0
   1.242 +    (mod -9 -3) 0
   1.243 +
   1.244 +    ; |num| < |div|
   1.245 +    (mod 2 5) 2       ; (2 / 5) * 5 + (2 mod 5)        = 0 * 5 + 2          = 2
   1.246 +    (mod 2 -5) -3     ; (2 / -5) * (-5) + (2 mod -5)   = (-1) * (-5) + (-3) = 2
   1.247 +    (mod -2 5) 3      ; (-2 / 5) * 5 + (-2 mod 5)      = (-1) * 5 + 3       = -2
   1.248 +    (mod -2 -5) -2    ; (-2 / -5) * (-5) + (-2 mod -5) = 0 * (-5) + (-2)    = -2
   1.249 +
   1.250 +    ; num = 0, div != 0
   1.251 +    (mod 0 3) 0       ; (0 / 3) * 3 + (0 mod 3) = 0 * 3 + 0 = 0
   1.252 +    (mod 0 -3) 0
   1.253 +  )
   1.254 +)
   1.255 +
   1.256 +;; rem & quot
   1.257 +;; http://en.wikipedia.org/wiki/Remainder
   1.258 +
   1.259 +(deftest test-rem
   1.260 +  ; wrong number of args
   1.261 +  (is (thrown? IllegalArgumentException (rem)))
   1.262 +  (is (thrown? IllegalArgumentException (rem 1)))
   1.263 +  (is (thrown? IllegalArgumentException (rem 3 2 1)))
   1.264 +
   1.265 +  ; divide by zero
   1.266 +  (is (thrown? ArithmeticException (rem 9 0)))
   1.267 +  (is (thrown? ArithmeticException (rem 0 0)))
   1.268 +  
   1.269 +  (are [x y] (= x y)
   1.270 +    (rem 4 2) 0
   1.271 +    (rem 3 2) 1
   1.272 +    (rem 6 4) 2
   1.273 +    (rem 0 5) 0
   1.274 +
   1.275 +    (rem 2 1/2) 0
   1.276 +    (rem 2/3 1/2) 1/6
   1.277 +    (rem 1 2/3) 1/3
   1.278 +
   1.279 +    (rem 4.0 2.0) 0.0
   1.280 +    (rem 4.5 2.0) 0.5
   1.281 +
   1.282 +    ; |num| > |div|, num != k * div
   1.283 +    (rem 42 5) 2      ; (8 * 5) + 2 == 42
   1.284 +    (rem 42 -5) 2     ; (-8 * -5) + 2 == 42
   1.285 +    (rem -42 5) -2    ; (-8 * 5) + -2 == -42
   1.286 +    (rem -42 -5) -2   ; (8 * -5) + -2 == -42
   1.287 +
   1.288 +    ; |num| > |div|, num = k * div
   1.289 +    (rem 9 3) 0
   1.290 +    (rem 9 -3) 0
   1.291 +    (rem -9 3) 0
   1.292 +    (rem -9 -3) 0
   1.293 +
   1.294 +    ; |num| < |div|
   1.295 +    (rem 2 5) 2
   1.296 +    (rem 2 -5) 2
   1.297 +    (rem -2 5) -2
   1.298 +    (rem -2 -5) -2
   1.299 +    
   1.300 +    ; num = 0, div != 0
   1.301 +    (rem 0 3) 0
   1.302 +    (rem 0 -3) 0
   1.303 +  )
   1.304 +)
   1.305 +
   1.306 +(deftest test-quot
   1.307 +  ; wrong number of args
   1.308 +  (is (thrown? IllegalArgumentException (quot)))
   1.309 +  (is (thrown? IllegalArgumentException (quot 1)))
   1.310 +  (is (thrown? IllegalArgumentException (quot 3 2 1)))
   1.311 +
   1.312 +  ; divide by zero
   1.313 +  (is (thrown? ArithmeticException (quot 9 0)))
   1.314 +  (is (thrown? ArithmeticException (quot 0 0)))
   1.315 +  
   1.316 +  (are [x y] (= x y)
   1.317 +    (quot 4 2) 2
   1.318 +    (quot 3 2) 1
   1.319 +    (quot 6 4) 1
   1.320 +    (quot 0 5) 0
   1.321 +
   1.322 +    (quot 2 1/2) 4
   1.323 +    (quot 2/3 1/2) 1
   1.324 +    (quot 1 2/3) 1
   1.325 +
   1.326 +    (quot 4.0 2.0) 2.0
   1.327 +    (quot 4.5 2.0) 2.0
   1.328 +
   1.329 +    ; |num| > |div|, num != k * div
   1.330 +    (quot 42 5) 8     ; (8 * 5) + 2 == 42
   1.331 +    (quot 42 -5) -8   ; (-8 * -5) + 2 == 42
   1.332 +    (quot -42 5) -8   ; (-8 * 5) + -2 == -42
   1.333 +    (quot -42 -5) 8   ; (8 * -5) + -2 == -42
   1.334 +
   1.335 +    ; |num| > |div|, num = k * div
   1.336 +    (quot 9 3) 3
   1.337 +    (quot 9 -3) -3
   1.338 +    (quot -9 3) -3
   1.339 +    (quot -9 -3) 3
   1.340 +
   1.341 +    ; |num| < |div|
   1.342 +    (quot 2 5) 0
   1.343 +    (quot 2 -5) 0
   1.344 +    (quot -2 5) 0
   1.345 +    (quot -2 -5) 0
   1.346 +
   1.347 +    ; num = 0, div != 0
   1.348 +    (quot 0 3) 0
   1.349 +    (quot 0 -3) 0
   1.350 +  )
   1.351 +)
   1.352 +
   1.353 +
   1.354 +;; *** Predicates ***
   1.355 +
   1.356 +;; pos? zero? neg?
   1.357 +
   1.358 +(deftest test-pos?-zero?-neg?
   1.359 +  (let [nums [[(byte 2) (byte 0) (byte -2)]
   1.360 +              [(short 3) (short 0) (short -3)]
   1.361 +              [(int 4) (int 0) (int -4)]
   1.362 +              [(long 5) (long 0) (long -5)]
   1.363 +              [(bigint 6) (bigint 0) (bigint -6)]
   1.364 +              [(float 7) (float 0) (float -7)]
   1.365 +              [(double 8) (double 0) (double -8)]
   1.366 +              [(bigdec 9) (bigdec 0) (bigdec -9)]
   1.367 +              [2/3 0 -2/3]]
   1.368 +        pred-result [[pos?  [true false false]]
   1.369 +                     [zero? [false true false]]
   1.370 +                     [neg?  [false false true]]] ]
   1.371 +    (doseq [pr pred-result]
   1.372 +      (doseq [n nums]
   1.373 +        (is (= (map (first pr) n) (second pr))
   1.374 +          (pr-str (first pr) n))))))
   1.375 +
   1.376 +
   1.377 +;; even? odd?
   1.378 +
   1.379 +(deftest test-even?
   1.380 +  (are [x] (true? x)
   1.381 +    (even? -4)
   1.382 +    (not (even? -3))
   1.383 +    (even? 0)
   1.384 +    (not (even? 5))
   1.385 +    (even? 8))
   1.386 +  (is (thrown? ArithmeticException (even? 1/2)))
   1.387 +  (is (thrown? ArithmeticException (even? (double 10)))))
   1.388 +
   1.389 +(deftest test-odd?
   1.390 +  (are [x] (true? x)
   1.391 +    (not (odd? -4))
   1.392 +    (odd? -3)
   1.393 +    (not (odd? 0))
   1.394 +    (odd? 5)
   1.395 +    (not (odd? 8)))
   1.396 +  (is (thrown? ArithmeticException (odd? 1/2)))
   1.397 +  (is (thrown? ArithmeticException (odd? (double 10)))))
   1.398 +
   1.399 +(defn- expt
   1.400 +  "clojure.contrib.math/expt is a better and much faster impl, but this works.
   1.401 +Math/pow overflows to Infinity."
   1.402 +  [x n] (apply * (replicate n x)))
   1.403 +
   1.404 +(deftest test-bit-shift-left
   1.405 +  (are [x y] (= x y)
   1.406 +       2r10 (bit-shift-left 2r1 1)
   1.407 +       2r100 (bit-shift-left 2r1 2)
   1.408 +       2r1000 (bit-shift-left 2r1 3)
   1.409 +       2r00101110 (bit-shift-left 2r00010111 1)
   1.410 +       2r00101110 (apply bit-shift-left [2r00010111 1])
   1.411 +       2r01 (bit-shift-left 2r10 -1)
   1.412 +       (expt 2 32) (bit-shift-left 1 32)
   1.413 +       (expt 2 10000) (bit-shift-left 1 10000)
   1.414 +       ))
   1.415 +
   1.416 +(deftest test-bit-shift-right
   1.417 +  (are [x y] (= x y)
   1.418 +       2r0 (bit-shift-right 2r1 1)
   1.419 +       2r010 (bit-shift-right 2r100 1)
   1.420 +       2r001 (bit-shift-right 2r100 2)
   1.421 +       2r000 (bit-shift-right 2r100 3)
   1.422 +       2r0001011 (bit-shift-right 2r00010111 1)
   1.423 +       2r0001011 (apply bit-shift-right [2r00010111 1])
   1.424 +       2r100 (bit-shift-right 2r10 -1)
   1.425 +       1 (bit-shift-right (expt 2 32) 32)
   1.426 +       1 (bit-shift-right (expt 2 10000) 10000)
   1.427 +       ))
   1.428 +
   1.429 +
   1.430 +;; arrays
   1.431 +(deftest test-array-types
   1.432 +  (are [x y z] (= (Class/forName x) (class y) (class z))
   1.433 +       "[Z" (boolean-array 1) (booleans (boolean-array 1 true))
   1.434 +       "[B" (byte-array 1) (bytes (byte-array 1 (byte 1)))
   1.435 +       "[C" (char-array 1) (chars (char-array 1 \a))
   1.436 +       "[S" (short-array 1) (shorts (short-array 1 (short 1)))
   1.437 +       "[F" (float-array 1) (floats (float-array 1 1))
   1.438 +       "[D" (double-array 1) (doubles (double-array 1 1))
   1.439 +       "[I" (int-array 1) (ints (int-array 1 1))
   1.440 +       "[J" (long-array 1) (longs (long-array 1 1))))
   1.441 +
   1.442 +
   1.443 +(deftest test-ratios
   1.444 +  (is (= (denominator 1/2) 2))
   1.445 +  (is (= (numerator 1/2) 1))
   1.446 +  (is (= (bigint (/ 100000000000000000000 3)) 33333333333333333333))
   1.447 +  (is (= (long 10000000000000000000/3) 3333333333333333333)))