annotate 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
rev   line source
rlm@10 1 ; Copyright (c) Rich Hickey. All rights reserved.
rlm@10 2 ; The use and distribution terms for this software are covered by the
rlm@10 3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 4 ; which can be found in the file epl-v10.html at the root of this distribution.
rlm@10 5 ; By using this software in any fashion, you are agreeing to be bound by
rlm@10 6 ; the terms of this license.
rlm@10 7 ; You must not remove this notice, or any other, from this software.
rlm@10 8
rlm@10 9 ; Author: Stephen C. Gilardi
rlm@10 10 ;; scgilardi (gmail)
rlm@10 11 ;; Created 30 October 2008
rlm@10 12 ;;
rlm@10 13
rlm@10 14 (ns clojure.test-clojure.numbers
rlm@10 15 (:use clojure.test))
rlm@10 16
rlm@10 17
rlm@10 18 ; TODO:
rlm@10 19 ; ==
rlm@10 20 ; and more...
rlm@10 21
rlm@10 22
rlm@10 23 ;; *** Types ***
rlm@10 24
rlm@10 25 (deftest Coerced-Byte
rlm@10 26 (let [v (byte 3)]
rlm@10 27 (are [x] (true? x)
rlm@10 28 (instance? Byte v)
rlm@10 29 (number? v)
rlm@10 30 (integer? v)
rlm@10 31 (rational? v))))
rlm@10 32
rlm@10 33 (deftest Coerced-Short
rlm@10 34 (let [v (short 3)]
rlm@10 35 (are [x] (true? x)
rlm@10 36 (instance? Short v)
rlm@10 37 (number? v)
rlm@10 38 (integer? v)
rlm@10 39 (rational? v))))
rlm@10 40
rlm@10 41 (deftest Coerced-Integer
rlm@10 42 (let [v (int 3)]
rlm@10 43 (are [x] (true? x)
rlm@10 44 (instance? Integer v)
rlm@10 45 (number? v)
rlm@10 46 (integer? v)
rlm@10 47 (rational? v))))
rlm@10 48
rlm@10 49 (deftest Coerced-Long
rlm@10 50 (let [v (long 3)]
rlm@10 51 (are [x] (true? x)
rlm@10 52 (instance? Long v)
rlm@10 53 (number? v)
rlm@10 54 (integer? v)
rlm@10 55 (rational? v))))
rlm@10 56
rlm@10 57 (deftest Coerced-BigInteger
rlm@10 58 (let [v (bigint 3)]
rlm@10 59 (are [x] (true? x)
rlm@10 60 (instance? BigInteger v)
rlm@10 61 (number? v)
rlm@10 62 (integer? v)
rlm@10 63 (rational? v))))
rlm@10 64
rlm@10 65 (deftest Coerced-Float
rlm@10 66 (let [v (float 3)]
rlm@10 67 (are [x] (true? x)
rlm@10 68 (instance? Float v)
rlm@10 69 (number? v)
rlm@10 70 (float? v))))
rlm@10 71
rlm@10 72 (deftest Coerced-Double
rlm@10 73 (let [v (double 3)]
rlm@10 74 (are [x] (true? x)
rlm@10 75 (instance? Double v)
rlm@10 76 (number? v)
rlm@10 77 (float? v))))
rlm@10 78
rlm@10 79 (deftest Coerced-BigDecimal
rlm@10 80 (let [v (bigdec 3)]
rlm@10 81 (are [x] (true? x)
rlm@10 82 (instance? BigDecimal v)
rlm@10 83 (number? v)
rlm@10 84 (decimal? v)
rlm@10 85 (not (float? v)))))
rlm@10 86
rlm@10 87
rlm@10 88 ;; *** Functions ***
rlm@10 89
rlm@10 90 (defonce DELTA 1e-12)
rlm@10 91
rlm@10 92 (deftest test-add
rlm@10 93 (are [x y] (= x y)
rlm@10 94 (+) 0
rlm@10 95 (+ 1) 1
rlm@10 96 (+ 1 2) 3
rlm@10 97 (+ 1 2 3) 6
rlm@10 98
rlm@10 99 (+ -1) -1
rlm@10 100 (+ -1 -2) -3
rlm@10 101 (+ -1 +2 -3) -2
rlm@10 102
rlm@10 103 (+ 1 -1) 0
rlm@10 104 (+ -1 1) 0
rlm@10 105
rlm@10 106 (+ 2/3) 2/3
rlm@10 107 (+ 2/3 1) 5/3
rlm@10 108 (+ 2/3 1/3) 1 )
rlm@10 109
rlm@10 110 (are [x y] (< (- x y) DELTA)
rlm@10 111 (+ 1.2) 1.2
rlm@10 112 (+ 1.1 2.4) 3.5
rlm@10 113 (+ 1.1 2.2 3.3) 6.6 )
rlm@10 114
rlm@10 115 (is (> (+ Integer/MAX_VALUE 10) Integer/MAX_VALUE)) ; no overflow
rlm@10 116 (is (thrown? ClassCastException (+ "ab" "cd"))) ) ; no string concatenation
rlm@10 117
rlm@10 118
rlm@10 119 (deftest test-subtract
rlm@10 120 (is (thrown? IllegalArgumentException (-)))
rlm@10 121 (are [x y] (= x y)
rlm@10 122 (- 1) -1
rlm@10 123 (- 1 2) -1
rlm@10 124 (- 1 2 3) -4
rlm@10 125
rlm@10 126 (- -2) 2
rlm@10 127 (- 1 -2) 3
rlm@10 128 (- 1 -2 -3) 6
rlm@10 129
rlm@10 130 (- 1 1) 0
rlm@10 131 (- -1 -1) 0
rlm@10 132
rlm@10 133 (- 2/3) -2/3
rlm@10 134 (- 2/3 1) -1/3
rlm@10 135 (- 2/3 1/3) 1/3 )
rlm@10 136
rlm@10 137 (are [x y] (< (- x y) DELTA)
rlm@10 138 (- 1.2) -1.2
rlm@10 139 (- 2.2 1.1) 1.1
rlm@10 140 (- 6.6 2.2 1.1) 3.3 )
rlm@10 141
rlm@10 142 (is (< (- Integer/MIN_VALUE 10) Integer/MIN_VALUE)) ) ; no underflow
rlm@10 143
rlm@10 144
rlm@10 145 (deftest test-multiply
rlm@10 146 (are [x y] (= x y)
rlm@10 147 (*) 1
rlm@10 148 (* 2) 2
rlm@10 149 (* 2 3) 6
rlm@10 150 (* 2 3 4) 24
rlm@10 151
rlm@10 152 (* -2) -2
rlm@10 153 (* 2 -3) -6
rlm@10 154 (* 2 -3 -1) 6
rlm@10 155
rlm@10 156 (* 1/2) 1/2
rlm@10 157 (* 1/2 1/3) 1/6
rlm@10 158 (* 1/2 1/3 -1/4) -1/24 )
rlm@10 159
rlm@10 160 (are [x y] (< (- x y) DELTA)
rlm@10 161 (* 1.2) 1.2
rlm@10 162 (* 2.0 1.2) 2.4
rlm@10 163 (* 3.5 2.0 1.2) 8.4 )
rlm@10 164
rlm@10 165 (is (> (* 3 (int (/ Integer/MAX_VALUE 2.0))) Integer/MAX_VALUE)) ) ; no overflow
rlm@10 166
rlm@10 167 (deftest test-ratios-simplify-to-ints-where-appropriate
rlm@10 168 (testing "negative denominator (assembla #275)"
rlm@10 169 (is (integer? (/ 1 -1/2)))
rlm@10 170 (is (integer? (/ 0 -1/2)))))
rlm@10 171
rlm@10 172 (deftest test-divide
rlm@10 173 (are [x y] (= x y)
rlm@10 174 (/ 1) 1
rlm@10 175 (/ 2) 1/2
rlm@10 176 (/ 3 2) 3/2
rlm@10 177 (/ 4 2) 2
rlm@10 178 (/ 24 3 2) 4
rlm@10 179 (/ 24 3 2 -1) -4
rlm@10 180
rlm@10 181 (/ -1) -1
rlm@10 182 (/ -2) -1/2
rlm@10 183 (/ -3 -2) 3/2
rlm@10 184 (/ -4 -2) 2
rlm@10 185 (/ -4 2) -2 )
rlm@10 186
rlm@10 187 (are [x y] (< (- x y) DELTA)
rlm@10 188 (/ 4.5 3) 1.5
rlm@10 189 (/ 4.5 3.0 3.0) 0.5 )
rlm@10 190
rlm@10 191 (is (thrown? ArithmeticException (/ 0)))
rlm@10 192 (is (thrown? ArithmeticException (/ 2 0)))
rlm@10 193 (is (thrown? IllegalArgumentException (/))) )
rlm@10 194
rlm@10 195
rlm@10 196 ;; mod
rlm@10 197 ;; http://en.wikipedia.org/wiki/Modulo_operation
rlm@10 198 ;; http://mathforum.org/library/drmath/view/52343.html
rlm@10 199 ;;
rlm@10 200 ;; is mod correct?
rlm@10 201 ;; http://groups.google.com/group/clojure/browse_frm/thread/2a0ee4d248f3d131#
rlm@10 202 ;;
rlm@10 203 ;; Issue 23: mod (modulo) operator
rlm@10 204 ;; http://code.google.com/p/clojure/issues/detail?id=23
rlm@10 205
rlm@10 206 (deftest test-mod
rlm@10 207 ; wrong number of args
rlm@10 208 (is (thrown? IllegalArgumentException (mod)))
rlm@10 209 (is (thrown? IllegalArgumentException (mod 1)))
rlm@10 210 (is (thrown? IllegalArgumentException (mod 3 2 1)))
rlm@10 211
rlm@10 212 ; divide by zero
rlm@10 213 (is (thrown? ArithmeticException (mod 9 0)))
rlm@10 214 (is (thrown? ArithmeticException (mod 0 0)))
rlm@10 215
rlm@10 216 (are [x y] (= x y)
rlm@10 217 (mod 4 2) 0
rlm@10 218 (mod 3 2) 1
rlm@10 219 (mod 6 4) 2
rlm@10 220 (mod 0 5) 0
rlm@10 221
rlm@10 222 (mod 2 1/2) 0
rlm@10 223 (mod 2/3 1/2) 1/6
rlm@10 224 (mod 1 2/3) 1/3
rlm@10 225
rlm@10 226 (mod 4.0 2.0) 0.0
rlm@10 227 (mod 4.5 2.0) 0.5
rlm@10 228
rlm@10 229 ; |num| > |div|, num != k * div
rlm@10 230 (mod 42 5) 2 ; (42 / 5) * 5 + (42 mod 5) = 8 * 5 + 2 = 42
rlm@10 231 (mod 42 -5) -3 ; (42 / -5) * (-5) + (42 mod -5) = -9 * (-5) + (-3) = 42
rlm@10 232 (mod -42 5) 3 ; (-42 / 5) * 5 + (-42 mod 5) = -9 * 5 + 3 = -42
rlm@10 233 (mod -42 -5) -2 ; (-42 / -5) * (-5) + (-42 mod -5) = 8 * (-5) + (-2) = -42
rlm@10 234
rlm@10 235 ; |num| > |div|, num = k * div
rlm@10 236 (mod 9 3) 0 ; (9 / 3) * 3 + (9 mod 3) = 3 * 3 + 0 = 9
rlm@10 237 (mod 9 -3) 0
rlm@10 238 (mod -9 3) 0
rlm@10 239 (mod -9 -3) 0
rlm@10 240
rlm@10 241 ; |num| < |div|
rlm@10 242 (mod 2 5) 2 ; (2 / 5) * 5 + (2 mod 5) = 0 * 5 + 2 = 2
rlm@10 243 (mod 2 -5) -3 ; (2 / -5) * (-5) + (2 mod -5) = (-1) * (-5) + (-3) = 2
rlm@10 244 (mod -2 5) 3 ; (-2 / 5) * 5 + (-2 mod 5) = (-1) * 5 + 3 = -2
rlm@10 245 (mod -2 -5) -2 ; (-2 / -5) * (-5) + (-2 mod -5) = 0 * (-5) + (-2) = -2
rlm@10 246
rlm@10 247 ; num = 0, div != 0
rlm@10 248 (mod 0 3) 0 ; (0 / 3) * 3 + (0 mod 3) = 0 * 3 + 0 = 0
rlm@10 249 (mod 0 -3) 0
rlm@10 250 )
rlm@10 251 )
rlm@10 252
rlm@10 253 ;; rem & quot
rlm@10 254 ;; http://en.wikipedia.org/wiki/Remainder
rlm@10 255
rlm@10 256 (deftest test-rem
rlm@10 257 ; wrong number of args
rlm@10 258 (is (thrown? IllegalArgumentException (rem)))
rlm@10 259 (is (thrown? IllegalArgumentException (rem 1)))
rlm@10 260 (is (thrown? IllegalArgumentException (rem 3 2 1)))
rlm@10 261
rlm@10 262 ; divide by zero
rlm@10 263 (is (thrown? ArithmeticException (rem 9 0)))
rlm@10 264 (is (thrown? ArithmeticException (rem 0 0)))
rlm@10 265
rlm@10 266 (are [x y] (= x y)
rlm@10 267 (rem 4 2) 0
rlm@10 268 (rem 3 2) 1
rlm@10 269 (rem 6 4) 2
rlm@10 270 (rem 0 5) 0
rlm@10 271
rlm@10 272 (rem 2 1/2) 0
rlm@10 273 (rem 2/3 1/2) 1/6
rlm@10 274 (rem 1 2/3) 1/3
rlm@10 275
rlm@10 276 (rem 4.0 2.0) 0.0
rlm@10 277 (rem 4.5 2.0) 0.5
rlm@10 278
rlm@10 279 ; |num| > |div|, num != k * div
rlm@10 280 (rem 42 5) 2 ; (8 * 5) + 2 == 42
rlm@10 281 (rem 42 -5) 2 ; (-8 * -5) + 2 == 42
rlm@10 282 (rem -42 5) -2 ; (-8 * 5) + -2 == -42
rlm@10 283 (rem -42 -5) -2 ; (8 * -5) + -2 == -42
rlm@10 284
rlm@10 285 ; |num| > |div|, num = k * div
rlm@10 286 (rem 9 3) 0
rlm@10 287 (rem 9 -3) 0
rlm@10 288 (rem -9 3) 0
rlm@10 289 (rem -9 -3) 0
rlm@10 290
rlm@10 291 ; |num| < |div|
rlm@10 292 (rem 2 5) 2
rlm@10 293 (rem 2 -5) 2
rlm@10 294 (rem -2 5) -2
rlm@10 295 (rem -2 -5) -2
rlm@10 296
rlm@10 297 ; num = 0, div != 0
rlm@10 298 (rem 0 3) 0
rlm@10 299 (rem 0 -3) 0
rlm@10 300 )
rlm@10 301 )
rlm@10 302
rlm@10 303 (deftest test-quot
rlm@10 304 ; wrong number of args
rlm@10 305 (is (thrown? IllegalArgumentException (quot)))
rlm@10 306 (is (thrown? IllegalArgumentException (quot 1)))
rlm@10 307 (is (thrown? IllegalArgumentException (quot 3 2 1)))
rlm@10 308
rlm@10 309 ; divide by zero
rlm@10 310 (is (thrown? ArithmeticException (quot 9 0)))
rlm@10 311 (is (thrown? ArithmeticException (quot 0 0)))
rlm@10 312
rlm@10 313 (are [x y] (= x y)
rlm@10 314 (quot 4 2) 2
rlm@10 315 (quot 3 2) 1
rlm@10 316 (quot 6 4) 1
rlm@10 317 (quot 0 5) 0
rlm@10 318
rlm@10 319 (quot 2 1/2) 4
rlm@10 320 (quot 2/3 1/2) 1
rlm@10 321 (quot 1 2/3) 1
rlm@10 322
rlm@10 323 (quot 4.0 2.0) 2.0
rlm@10 324 (quot 4.5 2.0) 2.0
rlm@10 325
rlm@10 326 ; |num| > |div|, num != k * div
rlm@10 327 (quot 42 5) 8 ; (8 * 5) + 2 == 42
rlm@10 328 (quot 42 -5) -8 ; (-8 * -5) + 2 == 42
rlm@10 329 (quot -42 5) -8 ; (-8 * 5) + -2 == -42
rlm@10 330 (quot -42 -5) 8 ; (8 * -5) + -2 == -42
rlm@10 331
rlm@10 332 ; |num| > |div|, num = k * div
rlm@10 333 (quot 9 3) 3
rlm@10 334 (quot 9 -3) -3
rlm@10 335 (quot -9 3) -3
rlm@10 336 (quot -9 -3) 3
rlm@10 337
rlm@10 338 ; |num| < |div|
rlm@10 339 (quot 2 5) 0
rlm@10 340 (quot 2 -5) 0
rlm@10 341 (quot -2 5) 0
rlm@10 342 (quot -2 -5) 0
rlm@10 343
rlm@10 344 ; num = 0, div != 0
rlm@10 345 (quot 0 3) 0
rlm@10 346 (quot 0 -3) 0
rlm@10 347 )
rlm@10 348 )
rlm@10 349
rlm@10 350
rlm@10 351 ;; *** Predicates ***
rlm@10 352
rlm@10 353 ;; pos? zero? neg?
rlm@10 354
rlm@10 355 (deftest test-pos?-zero?-neg?
rlm@10 356 (let [nums [[(byte 2) (byte 0) (byte -2)]
rlm@10 357 [(short 3) (short 0) (short -3)]
rlm@10 358 [(int 4) (int 0) (int -4)]
rlm@10 359 [(long 5) (long 0) (long -5)]
rlm@10 360 [(bigint 6) (bigint 0) (bigint -6)]
rlm@10 361 [(float 7) (float 0) (float -7)]
rlm@10 362 [(double 8) (double 0) (double -8)]
rlm@10 363 [(bigdec 9) (bigdec 0) (bigdec -9)]
rlm@10 364 [2/3 0 -2/3]]
rlm@10 365 pred-result [[pos? [true false false]]
rlm@10 366 [zero? [false true false]]
rlm@10 367 [neg? [false false true]]] ]
rlm@10 368 (doseq [pr pred-result]
rlm@10 369 (doseq [n nums]
rlm@10 370 (is (= (map (first pr) n) (second pr))
rlm@10 371 (pr-str (first pr) n))))))
rlm@10 372
rlm@10 373
rlm@10 374 ;; even? odd?
rlm@10 375
rlm@10 376 (deftest test-even?
rlm@10 377 (are [x] (true? x)
rlm@10 378 (even? -4)
rlm@10 379 (not (even? -3))
rlm@10 380 (even? 0)
rlm@10 381 (not (even? 5))
rlm@10 382 (even? 8))
rlm@10 383 (is (thrown? ArithmeticException (even? 1/2)))
rlm@10 384 (is (thrown? ArithmeticException (even? (double 10)))))
rlm@10 385
rlm@10 386 (deftest test-odd?
rlm@10 387 (are [x] (true? x)
rlm@10 388 (not (odd? -4))
rlm@10 389 (odd? -3)
rlm@10 390 (not (odd? 0))
rlm@10 391 (odd? 5)
rlm@10 392 (not (odd? 8)))
rlm@10 393 (is (thrown? ArithmeticException (odd? 1/2)))
rlm@10 394 (is (thrown? ArithmeticException (odd? (double 10)))))
rlm@10 395
rlm@10 396 (defn- expt
rlm@10 397 "clojure.contrib.math/expt is a better and much faster impl, but this works.
rlm@10 398 Math/pow overflows to Infinity."
rlm@10 399 [x n] (apply * (replicate n x)))
rlm@10 400
rlm@10 401 (deftest test-bit-shift-left
rlm@10 402 (are [x y] (= x y)
rlm@10 403 2r10 (bit-shift-left 2r1 1)
rlm@10 404 2r100 (bit-shift-left 2r1 2)
rlm@10 405 2r1000 (bit-shift-left 2r1 3)
rlm@10 406 2r00101110 (bit-shift-left 2r00010111 1)
rlm@10 407 2r00101110 (apply bit-shift-left [2r00010111 1])
rlm@10 408 2r01 (bit-shift-left 2r10 -1)
rlm@10 409 (expt 2 32) (bit-shift-left 1 32)
rlm@10 410 (expt 2 10000) (bit-shift-left 1 10000)
rlm@10 411 ))
rlm@10 412
rlm@10 413 (deftest test-bit-shift-right
rlm@10 414 (are [x y] (= x y)
rlm@10 415 2r0 (bit-shift-right 2r1 1)
rlm@10 416 2r010 (bit-shift-right 2r100 1)
rlm@10 417 2r001 (bit-shift-right 2r100 2)
rlm@10 418 2r000 (bit-shift-right 2r100 3)
rlm@10 419 2r0001011 (bit-shift-right 2r00010111 1)
rlm@10 420 2r0001011 (apply bit-shift-right [2r00010111 1])
rlm@10 421 2r100 (bit-shift-right 2r10 -1)
rlm@10 422 1 (bit-shift-right (expt 2 32) 32)
rlm@10 423 1 (bit-shift-right (expt 2 10000) 10000)
rlm@10 424 ))
rlm@10 425
rlm@10 426
rlm@10 427 ;; arrays
rlm@10 428 (deftest test-array-types
rlm@10 429 (are [x y z] (= (Class/forName x) (class y) (class z))
rlm@10 430 "[Z" (boolean-array 1) (booleans (boolean-array 1 true))
rlm@10 431 "[B" (byte-array 1) (bytes (byte-array 1 (byte 1)))
rlm@10 432 "[C" (char-array 1) (chars (char-array 1 \a))
rlm@10 433 "[S" (short-array 1) (shorts (short-array 1 (short 1)))
rlm@10 434 "[F" (float-array 1) (floats (float-array 1 1))
rlm@10 435 "[D" (double-array 1) (doubles (double-array 1 1))
rlm@10 436 "[I" (int-array 1) (ints (int-array 1 1))
rlm@10 437 "[J" (long-array 1) (longs (long-array 1 1))))
rlm@10 438
rlm@10 439
rlm@10 440 (deftest test-ratios
rlm@10 441 (is (= (denominator 1/2) 2))
rlm@10 442 (is (= (numerator 1/2) 1))
rlm@10 443 (is (= (bigint (/ 100000000000000000000 3)) 33333333333333333333))
rlm@10 444 (is (= (long 10000000000000000000/3) 3333333333333333333)))