~ubuntu-branches/ubuntu/maverick/commons-math/maverick

« back to all changes in this revision

Viewing changes to src/test/java/org/apache/commons/math/util/MathUtilsTest.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-08-22 01:13:25 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090822011325-hi4peq1ua5weguwn
Tags: 2.0-1
* New upstream release.
* Set Maintainer field to Debian Java Team
* Add myself as Uploaders
* Switch to Quilt patch system:
  - Refresh all patchs
  - Remove B-D on dpatch, Add B-D on quilt
  - Include patchsys-quilt.mk in debian/rules
* Bump Standards-Version to 3.8.3:
  - Add a README.source to describe patch system
* Maven POMs:
  - Add a Build-Depends-Indep dependency on maven-repo-helper
  - Use mh_installpom and mh_installjar to install the POM and the jar to the
    Maven repository
* Use default-jdk/jre:
  - Depends on java5-runtime-headless
  - Build-Depends on default-jdk
  - Use /usr/lib/jvm/default-java as JAVA_HOME
* Move api documentation to /usr/share/doc/libcommons-math-java/api
* Build-Depends on junit4 instead of junit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements. See the NOTICE file distributed with this
 
4
 * work for additional information regarding copyright ownership. The ASF
 
5
 * licenses this file to You under the Apache License, Version 2.0 (the
 
6
 * "License"); you may not use this file except in compliance with the License.
 
7
 * You may obtain a copy of the License at
 
8
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 
9
 * or agreed to in writing, software distributed under the License is
 
10
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
11
 * KIND, either express or implied. See the License for the specific language
 
12
 * governing permissions and limitations under the License.
 
13
 */
 
14
package org.apache.commons.math.util;
 
15
 
 
16
import java.math.BigDecimal;
 
17
import java.math.BigInteger;
 
18
import java.util.ArrayList;
 
19
import java.util.HashMap;
 
20
import java.util.List;
 
21
import java.util.Map;
 
22
 
 
23
import junit.framework.Test;
 
24
import junit.framework.TestCase;
 
25
import junit.framework.TestSuite;
 
26
 
 
27
import org.apache.commons.math.random.RandomDataImpl;
 
28
import org.apache.commons.math.TestUtils;
 
29
 
 
30
/**
 
31
 * Test cases for the MathUtils class.
 
32
 * @version $Revision: 790243 $ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug
 
33
 *          2007) $
 
34
 */
 
35
public final class MathUtilsTest extends TestCase {
 
36
 
 
37
    public MathUtilsTest(String name) {
 
38
        super(name);
 
39
    }
 
40
 
 
41
    public static Test suite() {
 
42
        TestSuite suite = new TestSuite(MathUtilsTest.class);
 
43
        suite.setName("MathUtils Tests");
 
44
        return suite;
 
45
    }
 
46
 
 
47
    /** cached binomial coefficients */
 
48
    private static final List<Map<Integer, Long>> binomialCache = new ArrayList<Map<Integer, Long>>();
 
49
 
 
50
    /**
 
51
     * Exact (caching) recursive implementation to test against
 
52
     */
 
53
    private long binomialCoefficient(int n, int k) throws ArithmeticException {
 
54
        if (binomialCache.size() > n) {
 
55
            Long cachedResult = binomialCache.get(n).get(Integer.valueOf(k));
 
56
            if (cachedResult != null) {
 
57
                return cachedResult.longValue();
 
58
            }
 
59
        }
 
60
        long result = -1;
 
61
        if ((n == k) || (k == 0)) {
 
62
            result = 1;
 
63
        } else if ((k == 1) || (k == n - 1)) {
 
64
            result = n;
 
65
        } else {
 
66
            // Reduce stack depth for larger values of n
 
67
            if (k < n - 100) {
 
68
                binomialCoefficient(n - 100, k);
 
69
            }
 
70
            if (k > 100) {
 
71
                binomialCoefficient(n - 100, k - 100);
 
72
            }
 
73
            result = MathUtils.addAndCheck(binomialCoefficient(n - 1, k - 1),
 
74
                binomialCoefficient(n - 1, k));
 
75
        }
 
76
        if (result == -1) {
 
77
            throw new ArithmeticException(
 
78
                "error computing binomial coefficient");
 
79
        }
 
80
        for (int i = binomialCache.size(); i < n + 1; i++) {
 
81
            binomialCache.add(new HashMap<Integer, Long>());
 
82
        }
 
83
        binomialCache.get(n).put(Integer.valueOf(k), Long.valueOf(result));
 
84
        return result;
 
85
    }
 
86
 
 
87
    /**
 
88
     * Exact direct multiplication implementation to test against
 
89
     */
 
90
    private long factorial(int n) {
 
91
        long result = 1;
 
92
        for (int i = 2; i <= n; i++) {
 
93
            result *= i;
 
94
        }
 
95
        return result;
 
96
    }
 
97
 
 
98
    /** Verify that b(0,0) = 1 */
 
99
    public void test0Choose0() {
 
100
        assertEquals(MathUtils.binomialCoefficientDouble(0, 0), 1d, 0);
 
101
        assertEquals(MathUtils.binomialCoefficientLog(0, 0), 0d, 0);
 
102
        assertEquals(MathUtils.binomialCoefficient(0, 0), 1);
 
103
    }
 
104
 
 
105
    public void testAddAndCheck() {
 
106
        int big = Integer.MAX_VALUE;
 
107
        int bigNeg = Integer.MIN_VALUE;
 
108
        assertEquals(big, MathUtils.addAndCheck(big, 0));
 
109
        try {
 
110
            MathUtils.addAndCheck(big, 1);
 
111
            fail("Expecting ArithmeticException");
 
112
        } catch (ArithmeticException ex) {
 
113
        }
 
114
        try {
 
115
            MathUtils.addAndCheck(bigNeg, -1);
 
116
            fail("Expecting ArithmeticException");
 
117
        } catch (ArithmeticException ex) {
 
118
        }
 
119
    }
 
120
 
 
121
    public void testAddAndCheckLong() {
 
122
        long max = Long.MAX_VALUE;
 
123
        long min = Long.MIN_VALUE;
 
124
        assertEquals(max, MathUtils.addAndCheck(max, 0L));
 
125
        assertEquals(min, MathUtils.addAndCheck(min, 0L));
 
126
        assertEquals(max, MathUtils.addAndCheck(0L, max));
 
127
        assertEquals(min, MathUtils.addAndCheck(0L, min));
 
128
        assertEquals(1, MathUtils.addAndCheck(-1L, 2L));
 
129
        assertEquals(1, MathUtils.addAndCheck(2L, -1L));
 
130
        assertEquals(-3, MathUtils.addAndCheck(-2L, -1L));
 
131
        assertEquals(min, MathUtils.addAndCheck(min + 1, -1L));
 
132
        testAddAndCheckLongFailure(max, 1L);
 
133
        testAddAndCheckLongFailure(min, -1L);
 
134
        testAddAndCheckLongFailure(1L, max);
 
135
        testAddAndCheckLongFailure(-1L, min);
 
136
    }
 
137
 
 
138
    private void testAddAndCheckLongFailure(long a, long b) {
 
139
        try {
 
140
            MathUtils.addAndCheck(a, b);
 
141
            fail("Expecting ArithmeticException");
 
142
        } catch (ArithmeticException ex) {
 
143
            // success
 
144
        }
 
145
    }
 
146
 
 
147
    public void testBinomialCoefficient() {
 
148
        long[] bcoef5 = {
 
149
            1,
 
150
            5,
 
151
            10,
 
152
            10,
 
153
            5,
 
154
            1 };
 
155
        long[] bcoef6 = {
 
156
            1,
 
157
            6,
 
158
            15,
 
159
            20,
 
160
            15,
 
161
            6,
 
162
            1 };
 
163
        for (int i = 0; i < 6; i++) {
 
164
            assertEquals("5 choose " + i, bcoef5[i], MathUtils.binomialCoefficient(5, i));
 
165
        }
 
166
        for (int i = 0; i < 7; i++) {
 
167
            assertEquals("6 choose " + i, bcoef6[i], MathUtils.binomialCoefficient(6, i));
 
168
        }
 
169
 
 
170
        for (int n = 1; n < 10; n++) {
 
171
            for (int k = 0; k <= n; k++) {
 
172
                assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficient(n, k));
 
173
                assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficientDouble(n, k), Double.MIN_VALUE);
 
174
                assertEquals(n + " choose " + k, Math.log(binomialCoefficient(n, k)), MathUtils.binomialCoefficientLog(n, k), 10E-12);
 
175
            }
 
176
        }
 
177
 
 
178
        int[] n = { 34, 66, 100, 1500, 1500 };
 
179
        int[] k = { 17, 33, 10, 1500 - 4, 4 };
 
180
        for (int i = 0; i < n.length; i++) {
 
181
            long expected = binomialCoefficient(n[i], k[i]);
 
182
            assertEquals(n[i] + " choose " + k[i], expected,
 
183
                MathUtils.binomialCoefficient(n[i], k[i]));
 
184
            assertEquals(n[i] + " choose " + k[i], expected,
 
185
                MathUtils.binomialCoefficientDouble(n[i], k[i]), 0.0);
 
186
            assertEquals("log(" + n[i] + " choose " + k[i] + ")", Math.log(expected),
 
187
                MathUtils.binomialCoefficientLog(n[i], k[i]), 0.0);
 
188
        }
 
189
    }
 
190
 
 
191
    /**
 
192
     * Tests correctness for large n and sharpness of upper bound in API doc
 
193
     * JIRA: MATH-241
 
194
     */
 
195
    public void testBinomialCoefficientLarge() throws Exception {
 
196
        // This tests all legal and illegal values for n <= 200.
 
197
        for (int n = 0; n <= 200; n++) {
 
198
            for (int k = 0; k <= n; k++) {
 
199
                long ourResult = -1;
 
200
                long exactResult = -1;
 
201
                boolean shouldThrow = false;
 
202
                boolean didThrow = false;
 
203
                try {
 
204
                    ourResult = MathUtils.binomialCoefficient(n, k);
 
205
                } catch (ArithmeticException ex) {
 
206
                    didThrow = true;
 
207
                }
 
208
                try {
 
209
                    exactResult = binomialCoefficient(n, k);
 
210
                } catch (ArithmeticException ex) {
 
211
                    shouldThrow = true;
 
212
                }
 
213
                assertEquals(n + " choose " + k, exactResult, ourResult);
 
214
                assertEquals(n + " choose " + k, shouldThrow, didThrow);
 
215
                assertTrue(n + " choose " + k, (n > 66 || !didThrow));
 
216
 
 
217
                if (!shouldThrow && exactResult > 1) {
 
218
                    assertEquals(n + " choose " + k, 1.,
 
219
                        MathUtils.binomialCoefficientDouble(n, k) / exactResult, 1e-10);
 
220
                    assertEquals(n + " choose " + k, 1,
 
221
                        MathUtils.binomialCoefficientLog(n, k) / Math.log(exactResult), 1e-10);
 
222
                }
 
223
            }
 
224
        }
 
225
 
 
226
        long ourResult = MathUtils.binomialCoefficient(300, 3);
 
227
        long exactResult = binomialCoefficient(300, 3);
 
228
        assertEquals(exactResult, ourResult);
 
229
 
 
230
        ourResult = MathUtils.binomialCoefficient(700, 697);
 
231
        exactResult = binomialCoefficient(700, 697);
 
232
        assertEquals(exactResult, ourResult);
 
233
 
 
234
        // This one should throw
 
235
        try {
 
236
            MathUtils.binomialCoefficient(700, 300);
 
237
            fail("Expecting ArithmeticException");
 
238
        } catch (ArithmeticException ex) {
 
239
            // Expected
 
240
        }
 
241
 
 
242
        int n = 10000;
 
243
        ourResult = MathUtils.binomialCoefficient(n, 3);
 
244
        exactResult = binomialCoefficient(n, 3);
 
245
        assertEquals(exactResult, ourResult);
 
246
        assertEquals(1, MathUtils.binomialCoefficientDouble(n, 3) / exactResult, 1e-10);
 
247
        assertEquals(1, MathUtils.binomialCoefficientLog(n, 3) / Math.log(exactResult), 1e-10);
 
248
 
 
249
    }
 
250
 
 
251
    public void testBinomialCoefficientFail() {
 
252
        try {
 
253
            MathUtils.binomialCoefficient(4, 5);
 
254
            fail("expecting IllegalArgumentException");
 
255
        } catch (IllegalArgumentException ex) {
 
256
            // ignored
 
257
        }
 
258
 
 
259
        try {
 
260
            MathUtils.binomialCoefficientDouble(4, 5);
 
261
            fail("expecting IllegalArgumentException");
 
262
        } catch (IllegalArgumentException ex) {
 
263
            // ignored
 
264
        }
 
265
 
 
266
        try {
 
267
            MathUtils.binomialCoefficientLog(4, 5);
 
268
            fail("expecting IllegalArgumentException");
 
269
        } catch (IllegalArgumentException ex) {
 
270
            // ignored
 
271
        }
 
272
 
 
273
        try {
 
274
            MathUtils.binomialCoefficient(-1, -2);
 
275
            fail("expecting IllegalArgumentException");
 
276
        } catch (IllegalArgumentException ex) {
 
277
            // ignored
 
278
        }
 
279
        try {
 
280
            MathUtils.binomialCoefficientDouble(-1, -2);
 
281
            fail("expecting IllegalArgumentException");
 
282
        } catch (IllegalArgumentException ex) {
 
283
            // ignored
 
284
        }
 
285
        try {
 
286
            MathUtils.binomialCoefficientLog(-1, -2);
 
287
            fail("expecting IllegalArgumentException");
 
288
        } catch (IllegalArgumentException ex) {
 
289
            // ignored
 
290
        }
 
291
 
 
292
        try {
 
293
            MathUtils.binomialCoefficient(67, 30);
 
294
            fail("expecting ArithmeticException");
 
295
        } catch (ArithmeticException ex) {
 
296
            // ignored
 
297
        }
 
298
        try {
 
299
            MathUtils.binomialCoefficient(67, 34);
 
300
            fail("expecting ArithmeticException");
 
301
        } catch (ArithmeticException ex) {
 
302
            // ignored
 
303
        }
 
304
        double x = MathUtils.binomialCoefficientDouble(1030, 515);
 
305
        assertTrue("expecting infinite binomial coefficient", Double
 
306
            .isInfinite(x));
 
307
    }
 
308
 
 
309
    public void testCompareTo() {
 
310
      assertEquals(0, MathUtils.compareTo(152.33, 152.32, .011));
 
311
      assertTrue(MathUtils.compareTo(152.308, 152.32, .011) < 0);
 
312
      assertTrue(MathUtils.compareTo(152.33, 152.318, .011) > 0);
 
313
    }
 
314
    
 
315
    public void testCosh() {
 
316
        double x = 3.0;
 
317
        double expected = 10.06766;
 
318
        assertEquals(expected, MathUtils.cosh(x), 1.0e-5);
 
319
    }
 
320
 
 
321
    public void testCoshNaN() {
 
322
        assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
 
323
    }
 
324
 
 
325
    public void testEquals() {
 
326
        double[] testArray = {
 
327
            Double.NaN,
 
328
            Double.POSITIVE_INFINITY,
 
329
            Double.NEGATIVE_INFINITY,
 
330
            1d,
 
331
            0d };
 
332
        for (int i = 0; i < testArray.length; i++) {
 
333
            for (int j = 0; j < testArray.length; j++) {
 
334
                if (i == j) {
 
335
                    assertTrue(MathUtils.equals(testArray[i], testArray[j]));
 
336
                    assertTrue(MathUtils.equals(testArray[j], testArray[i]));
 
337
                } else {
 
338
                    assertTrue(!MathUtils.equals(testArray[i], testArray[j]));
 
339
                    assertTrue(!MathUtils.equals(testArray[j], testArray[i]));
 
340
                }
 
341
            }
 
342
        }
 
343
    }
 
344
 
 
345
    public void testEqualsWithAllowedDelta() {
 
346
        assertTrue(MathUtils.equals(153.0000, 153.0000, .0625));
 
347
        assertTrue(MathUtils.equals(153.0000, 153.0625, .0625));
 
348
        assertTrue(MathUtils.equals(152.9375, 153.0000, .0625));
 
349
        assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1.0));
 
350
        assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
 
351
        assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0));
 
352
        assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
 
353
        assertFalse(MathUtils.equals(153.0000, 153.0625, .0624));
 
354
        assertFalse(MathUtils.equals(152.9374, 153.0000, .0625));
 
355
    }
 
356
 
 
357
    public void testEqualsWithAllowedUlps() {
 
358
        assertTrue(MathUtils.equals(153, 153, 1));
 
359
 
 
360
        assertTrue(MathUtils.equals(153, 153.00000000000003, 1));
 
361
        assertFalse(MathUtils.equals(153, 153.00000000000006, 1));
 
362
        assertTrue(MathUtils.equals(153, 152.99999999999997, 1));
 
363
        assertFalse(MathUtils.equals(153, 152.99999999999994, 1));
 
364
        
 
365
        assertTrue(MathUtils.equals(-128, -127.99999999999999, 1));
 
366
        assertFalse(MathUtils.equals(-128, -127.99999999999997, 1));
 
367
        assertTrue(MathUtils.equals(-128, -128.00000000000003, 1));
 
368
        assertFalse(MathUtils.equals(-128, -128.00000000000006, 1));
 
369
 
 
370
        assertTrue(MathUtils.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
 
371
        assertTrue(MathUtils.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
 
372
 
 
373
        assertTrue(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
 
374
        assertTrue(MathUtils.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
 
375
 
 
376
 
 
377
        assertTrue(MathUtils.equals(Double.NaN, Double.NaN, 1));
 
378
 
 
379
        assertFalse(MathUtils.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
 
380
    }
 
381
    
 
382
    public void testArrayEquals() {
 
383
        assertFalse(MathUtils.equals(new double[] { 1d }, null));
 
384
        assertFalse(MathUtils.equals(null, new double[] { 1d }));
 
385
        assertTrue(MathUtils.equals((double[]) null, (double[]) null));
 
386
 
 
387
        assertFalse(MathUtils.equals(new double[] { 1d }, new double[0]));
 
388
        assertTrue(MathUtils.equals(new double[] { 1d }, new double[] { 1d }));
 
389
        assertTrue(MathUtils.equals(new double[] {
 
390
                                      Double.NaN, Double.POSITIVE_INFINITY,
 
391
                                      Double.NEGATIVE_INFINITY, 1d, 0d
 
392
                                    }, new double[] {
 
393
                                      Double.NaN, Double.POSITIVE_INFINITY,
 
394
                                      Double.NEGATIVE_INFINITY, 1d, 0d
 
395
                                    }));
 
396
        assertFalse(MathUtils.equals(new double[] { Double.POSITIVE_INFINITY },
 
397
                                     new double[] { Double.NEGATIVE_INFINITY }));
 
398
        assertFalse(MathUtils.equals(new double[] { 1d },
 
399
                                     new double[] { MathUtils.nextAfter(1d, 2d) }));
 
400
 
 
401
    }
 
402
 
 
403
    public void testFactorial() {
 
404
        for (int i = 1; i < 21; i++) {
 
405
            assertEquals(i + "! ", factorial(i), MathUtils.factorial(i));
 
406
            assertEquals(i + "! ", factorial(i), MathUtils.factorialDouble(i), Double.MIN_VALUE);
 
407
            assertEquals(i + "! ", Math.log(factorial(i)), MathUtils.factorialLog(i), 10E-12);
 
408
        }
 
409
        
 
410
        assertEquals("0", 1, MathUtils.factorial(0));
 
411
        assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14);
 
412
        assertEquals("0", 0.0d, MathUtils.factorialLog(0), 1E-14);
 
413
    }
 
414
 
 
415
    public void testFactorialFail() {
 
416
        try {
 
417
            MathUtils.factorial(-1);
 
418
            fail("expecting IllegalArgumentException");
 
419
        } catch (IllegalArgumentException ex) {
 
420
            // ignored
 
421
        }
 
422
        try {
 
423
            MathUtils.factorialDouble(-1);
 
424
            fail("expecting IllegalArgumentException");
 
425
        } catch (IllegalArgumentException ex) {
 
426
            // ignored
 
427
        }
 
428
        try {
 
429
            MathUtils.factorialLog(-1);
 
430
            fail("expecting IllegalArgumentException");
 
431
        } catch (IllegalArgumentException ex) {
 
432
            // ignored
 
433
        }
 
434
        try {
 
435
            MathUtils.factorial(21);
 
436
            fail("expecting ArithmeticException");
 
437
        } catch (ArithmeticException ex) {
 
438
            // ignored
 
439
        }
 
440
        assertTrue("expecting infinite factorial value", Double.isInfinite(MathUtils.factorialDouble(171)));
 
441
    }
 
442
 
 
443
    public void testGcd() {
 
444
        int a = 30;
 
445
        int b = 50;
 
446
        int c = 77;
 
447
 
 
448
        assertEquals(0, MathUtils.gcd(0, 0));
 
449
 
 
450
        assertEquals(b, MathUtils.gcd(0, b));
 
451
        assertEquals(a, MathUtils.gcd(a, 0));
 
452
        assertEquals(b, MathUtils.gcd(0, -b));
 
453
        assertEquals(a, MathUtils.gcd(-a, 0));
 
454
 
 
455
        assertEquals(10, MathUtils.gcd(a, b));
 
456
        assertEquals(10, MathUtils.gcd(-a, b));
 
457
        assertEquals(10, MathUtils.gcd(a, -b));
 
458
        assertEquals(10, MathUtils.gcd(-a, -b));
 
459
 
 
460
        assertEquals(1, MathUtils.gcd(a, c));
 
461
        assertEquals(1, MathUtils.gcd(-a, c));
 
462
        assertEquals(1, MathUtils.gcd(a, -c));
 
463
        assertEquals(1, MathUtils.gcd(-a, -c));
 
464
 
 
465
        assertEquals(3 * (1<<15), MathUtils.gcd(3 * (1<<20), 9 * (1<<15)));
 
466
 
 
467
        assertEquals(Integer.MAX_VALUE, MathUtils.gcd(Integer.MAX_VALUE, 0));
 
468
        assertEquals(Integer.MAX_VALUE, MathUtils.gcd(-Integer.MAX_VALUE, 0));
 
469
        assertEquals(1<<30, MathUtils.gcd(1<<30, -Integer.MIN_VALUE));
 
470
        try {
 
471
            // gcd(Integer.MIN_VALUE, 0) > Integer.MAX_VALUE
 
472
            MathUtils.gcd(Integer.MIN_VALUE, 0);
 
473
            fail("expecting ArithmeticException");
 
474
        } catch (ArithmeticException expected) {
 
475
            // expected
 
476
        }
 
477
        try {
 
478
            // gcd(0, Integer.MIN_VALUE) > Integer.MAX_VALUE
 
479
            MathUtils.gcd(0, Integer.MIN_VALUE);
 
480
            fail("expecting ArithmeticException");
 
481
        } catch (ArithmeticException expected) {
 
482
            // expected
 
483
        }
 
484
        try {
 
485
            // gcd(Integer.MIN_VALUE, Integer.MIN_VALUE) > Integer.MAX_VALUE
 
486
            MathUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE);
 
487
            fail("expecting ArithmeticException");
 
488
        } catch (ArithmeticException expected) {
 
489
            // expected
 
490
        }
 
491
    }
 
492
 
 
493
    public void testHash() {
 
494
        double[] testArray = {
 
495
            Double.NaN,
 
496
            Double.POSITIVE_INFINITY,
 
497
            Double.NEGATIVE_INFINITY,
 
498
            1d,
 
499
            0d,
 
500
            1E-14,
 
501
            (1 + 1E-14),
 
502
            Double.MIN_VALUE,
 
503
            Double.MAX_VALUE };
 
504
        for (int i = 0; i < testArray.length; i++) {
 
505
            for (int j = 0; j < testArray.length; j++) {
 
506
                if (i == j) {
 
507
                    assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j]));
 
508
                    assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i]));
 
509
                } else {
 
510
                    assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j]));
 
511
                    assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i]));
 
512
                }
 
513
            }
 
514
        }
 
515
    }
 
516
 
 
517
    public void testArrayHash() {
 
518
        assertEquals(0, MathUtils.hash((double[]) null));
 
519
        assertEquals(MathUtils.hash(new double[] {
 
520
                                      Double.NaN, Double.POSITIVE_INFINITY,
 
521
                                      Double.NEGATIVE_INFINITY, 1d, 0d
 
522
                                    }),
 
523
                     MathUtils.hash(new double[] {
 
524
                                      Double.NaN, Double.POSITIVE_INFINITY,
 
525
                                      Double.NEGATIVE_INFINITY, 1d, 0d
 
526
                                    }));
 
527
        assertFalse(MathUtils.hash(new double[] { 1d }) ==
 
528
                    MathUtils.hash(new double[] { MathUtils.nextAfter(1d, 2d) }));
 
529
        assertFalse(MathUtils.hash(new double[] { 1d }) ==
 
530
                    MathUtils.hash(new double[] { 1d, 1d }));
 
531
    }
 
532
    
 
533
    /**
 
534
     * Make sure that permuted arrays do not hash to the same value.
 
535
     */
 
536
    public void testPermutedArrayHash() {
 
537
        double[] original = new double[10];
 
538
        double[] permuted = new double[10];
 
539
        RandomDataImpl random = new RandomDataImpl();
 
540
        
 
541
        // Generate 10 distinct random values
 
542
        for (int i = 0; i < 10; i++) {
 
543
            original[i] = random.nextUniform(i + 0.5, i + 0.75);
 
544
        }
 
545
        
 
546
        // Generate a random permutation, making sure it is not the identity
 
547
        boolean isIdentity = true;
 
548
        do {
 
549
            int[] permutation = random.nextPermutation(10, 10);
 
550
            for (int i = 0; i < 10; i++) {
 
551
                if (i != permutation[i]) {
 
552
                    isIdentity = false;
 
553
                }
 
554
                permuted[i] = original[permutation[i]];
 
555
            }
 
556
        } while (isIdentity);
 
557
        
 
558
        // Verify that permuted array has different hash
 
559
        assertFalse(MathUtils.hash(original) == MathUtils.hash(permuted));
 
560
    }
 
561
 
 
562
    public void testIndicatorByte() {
 
563
        assertEquals((byte)1, MathUtils.indicator((byte)2));
 
564
        assertEquals((byte)1, MathUtils.indicator((byte)0));
 
565
        assertEquals((byte)(-1), MathUtils.indicator((byte)(-2)));
 
566
    }
 
567
 
 
568
    public void testIndicatorDouble() {
 
569
        double delta = 0.0;
 
570
        assertEquals(1.0, MathUtils.indicator(2.0), delta);
 
571
        assertEquals(1.0, MathUtils.indicator(0.0), delta);
 
572
        assertEquals(-1.0, MathUtils.indicator(-2.0), delta);
 
573
        assertEquals(Double.NaN, MathUtils.indicator(Double.NaN));
 
574
    }
 
575
 
 
576
    public void testIndicatorFloat() {
 
577
        float delta = 0.0F;
 
578
        assertEquals(1.0F, MathUtils.indicator(2.0F), delta);
 
579
        assertEquals(1.0F, MathUtils.indicator(0.0F), delta);
 
580
        assertEquals(-1.0F, MathUtils.indicator(-2.0F), delta);
 
581
    }
 
582
 
 
583
    public void testIndicatorInt() {
 
584
        assertEquals(1, MathUtils.indicator((2)));
 
585
        assertEquals(1, MathUtils.indicator((0)));
 
586
        assertEquals((-1), MathUtils.indicator((-2)));
 
587
    }
 
588
 
 
589
    public void testIndicatorLong() {
 
590
        assertEquals(1L, MathUtils.indicator(2L));
 
591
        assertEquals(1L, MathUtils.indicator(0L));
 
592
        assertEquals(-1L, MathUtils.indicator(-2L));
 
593
    }
 
594
 
 
595
    public void testIndicatorShort() {
 
596
        assertEquals((short)1, MathUtils.indicator((short)2));
 
597
        assertEquals((short)1, MathUtils.indicator((short)0));
 
598
        assertEquals((short)(-1), MathUtils.indicator((short)(-2)));
 
599
    }
 
600
 
 
601
    public void testLcm() {
 
602
        int a = 30;
 
603
        int b = 50;
 
604
        int c = 77;
 
605
 
 
606
        assertEquals(0, MathUtils.lcm(0, b));
 
607
        assertEquals(0, MathUtils.lcm(a, 0));
 
608
        assertEquals(b, MathUtils.lcm(1, b));
 
609
        assertEquals(a, MathUtils.lcm(a, 1));
 
610
        assertEquals(150, MathUtils.lcm(a, b));
 
611
        assertEquals(150, MathUtils.lcm(-a, b));
 
612
        assertEquals(150, MathUtils.lcm(a, -b));
 
613
        assertEquals(150, MathUtils.lcm(-a, -b));
 
614
        assertEquals(2310, MathUtils.lcm(a, c));
 
615
 
 
616
        // Assert that no intermediate value overflows:
 
617
        // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b)
 
618
        assertEquals((1<<20)*15, MathUtils.lcm((1<<20)*3, (1<<20)*5));
 
619
 
 
620
        // Special case
 
621
        assertEquals(0, MathUtils.lcm(0, 0));
 
622
 
 
623
        try {
 
624
            // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
 
625
            MathUtils.lcm(Integer.MIN_VALUE, 1);
 
626
            fail("Expecting ArithmeticException");
 
627
        } catch (ArithmeticException ex) {
 
628
            // expected
 
629
        }
 
630
        
 
631
        try {
 
632
            // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
 
633
            MathUtils.lcm(Integer.MIN_VALUE, 1<<20);
 
634
            fail("Expecting ArithmeticException");
 
635
        } catch (ArithmeticException ex) {
 
636
            // expected
 
637
        }
 
638
 
 
639
        try {
 
640
            MathUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
 
641
            fail("Expecting ArithmeticException");
 
642
        } catch (ArithmeticException ex) {
 
643
            // expected
 
644
        }
 
645
    }
 
646
 
 
647
    public void testLog() {
 
648
        assertEquals(2.0, MathUtils.log(2, 4), 0);
 
649
        assertEquals(3.0, MathUtils.log(2, 8), 0);
 
650
        assertTrue(Double.isNaN(MathUtils.log(-1, 1)));
 
651
        assertTrue(Double.isNaN(MathUtils.log(1, -1)));
 
652
        assertTrue(Double.isNaN(MathUtils.log(0, 0)));
 
653
        assertEquals(0, MathUtils.log(0, 10), 0);
 
654
        assertEquals(Double.NEGATIVE_INFINITY, MathUtils.log(10, 0), 0);
 
655
    }
 
656
 
 
657
    public void testMulAndCheck() {
 
658
        int big = Integer.MAX_VALUE;
 
659
        int bigNeg = Integer.MIN_VALUE;
 
660
        assertEquals(big, MathUtils.mulAndCheck(big, 1));
 
661
        try {
 
662
            MathUtils.mulAndCheck(big, 2);
 
663
            fail("Expecting ArithmeticException");
 
664
        } catch (ArithmeticException ex) {
 
665
        }
 
666
        try {
 
667
            MathUtils.mulAndCheck(bigNeg, 2);
 
668
            fail("Expecting ArithmeticException");
 
669
        } catch (ArithmeticException ex) {
 
670
        }
 
671
    }
 
672
 
 
673
    public void testMulAndCheckLong() {
 
674
        long max = Long.MAX_VALUE;
 
675
        long min = Long.MIN_VALUE;
 
676
        assertEquals(max, MathUtils.mulAndCheck(max, 1L));
 
677
        assertEquals(min, MathUtils.mulAndCheck(min, 1L));
 
678
        assertEquals(0L, MathUtils.mulAndCheck(max, 0L));
 
679
        assertEquals(0L, MathUtils.mulAndCheck(min, 0L));
 
680
        assertEquals(max, MathUtils.mulAndCheck(1L, max));
 
681
        assertEquals(min, MathUtils.mulAndCheck(1L, min));
 
682
        assertEquals(0L, MathUtils.mulAndCheck(0L, max));
 
683
        assertEquals(0L, MathUtils.mulAndCheck(0L, min));
 
684
        assertEquals(1L, MathUtils.mulAndCheck(-1L, -1L));
 
685
        assertEquals(min, MathUtils.mulAndCheck(min / 2, 2));
 
686
        testMulAndCheckLongFailure(max, 2L);
 
687
        testMulAndCheckLongFailure(2L, max);
 
688
        testMulAndCheckLongFailure(min, 2L);
 
689
        testMulAndCheckLongFailure(2L, min);
 
690
        testMulAndCheckLongFailure(min, -1L);
 
691
        testMulAndCheckLongFailure(-1L, min);
 
692
    }
 
693
 
 
694
    private void testMulAndCheckLongFailure(long a, long b) {
 
695
        try {
 
696
            MathUtils.mulAndCheck(a, b);
 
697
            fail("Expecting ArithmeticException");
 
698
        } catch (ArithmeticException ex) {
 
699
            // success
 
700
        }
 
701
    }
 
702
 
 
703
    public void testNextAfter() {
 
704
        // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000
 
705
        assertEquals(16.0, MathUtils.nextAfter(15.999999999999998, 34.27555555555555), 0.0);
 
706
 
 
707
        // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe
 
708
        assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 34.27555555555555), 0.0);
 
709
 
 
710
        // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe
 
711
        assertEquals(15.999999999999996, MathUtils.nextAfter(15.999999999999998, 2.142222222222222), 0.0);
 
712
 
 
713
        // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe
 
714
        assertEquals(-15.999999999999996, MathUtils.nextAfter(-15.999999999999998, 2.142222222222222), 0.0);
 
715
 
 
716
        // 0x4020000000000000 0x404123456789abcd -> 4020000000000001
 
717
        assertEquals(8.000000000000002, MathUtils.nextAfter(8.0, 34.27555555555555), 0.0);
 
718
 
 
719
        // 0xc020000000000000 0x404123456789abcd -> c01fffffffffffff
 
720
        assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 34.27555555555555), 0.0);
 
721
 
 
722
        // 0x4020000000000000 0x400123456789abcd -> 401fffffffffffff
 
723
        assertEquals(7.999999999999999, MathUtils.nextAfter(8.0, 2.142222222222222), 0.0);
 
724
 
 
725
        // 0xc020000000000000 0x400123456789abcd -> c01fffffffffffff
 
726
        assertEquals(-7.999999999999999, MathUtils.nextAfter(-8.0, 2.142222222222222), 0.0);
 
727
 
 
728
        // 0x3f2e43753d36a223 0x3f2e43753d36a224 -> 3f2e43753d36a224
 
729
        assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.308922399667661E-4), 0.0);
 
730
 
 
731
        // 0x3f2e43753d36a223 0x3f2e43753d36a223 -> 3f2e43753d36a224
 
732
        assertEquals(2.308922399667661E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676606E-4), 0.0);
 
733
 
 
734
        // 0x3f2e43753d36a223 0x3f2e43753d36a222 -> 3f2e43753d36a222
 
735
        assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, 2.3089223996676603E-4), 0.0);
 
736
 
 
737
        // 0x3f2e43753d36a223 0xbf2e43753d36a224 -> 3f2e43753d36a222
 
738
        assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.308922399667661E-4), 0.0);
 
739
 
 
740
        // 0x3f2e43753d36a223 0xbf2e43753d36a223 -> 3f2e43753d36a222
 
741
        assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676606E-4), 0.0);
 
742
 
 
743
        // 0x3f2e43753d36a223 0xbf2e43753d36a222 -> 3f2e43753d36a222
 
744
        assertEquals(2.3089223996676603E-4, MathUtils.nextAfter(2.3089223996676606E-4, -2.3089223996676603E-4), 0.0);
 
745
 
 
746
        // 0xbf2e43753d36a223 0x3f2e43753d36a224 -> bf2e43753d36a222
 
747
        assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.308922399667661E-4), 0.0);
 
748
 
 
749
        // 0xbf2e43753d36a223 0x3f2e43753d36a223 -> bf2e43753d36a222
 
750
        assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676606E-4), 0.0);
 
751
 
 
752
        // 0xbf2e43753d36a223 0x3f2e43753d36a222 -> bf2e43753d36a222
 
753
        assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, 2.3089223996676603E-4), 0.0);
 
754
 
 
755
        // 0xbf2e43753d36a223 0xbf2e43753d36a224 -> bf2e43753d36a224
 
756
        assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.308922399667661E-4), 0.0);
 
757
 
 
758
        // 0xbf2e43753d36a223 0xbf2e43753d36a223 -> bf2e43753d36a224
 
759
        assertEquals(-2.308922399667661E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676606E-4), 0.0);
 
760
 
 
761
        // 0xbf2e43753d36a223 0xbf2e43753d36a222 -> bf2e43753d36a222
 
762
        assertEquals(-2.3089223996676603E-4, MathUtils.nextAfter(-2.3089223996676606E-4, -2.3089223996676603E-4), 0.0);
 
763
 
 
764
    }
 
765
 
 
766
    public void testNextAfterSpecialCases() {
 
767
        assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.NEGATIVE_INFINITY, 0)));
 
768
        assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.POSITIVE_INFINITY, 0)));
 
769
        assertTrue(Double.isNaN(MathUtils.nextAfter(Double.NaN, 0)));
 
770
        assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.MAX_VALUE, Double.POSITIVE_INFINITY)));
 
771
        assertTrue(Double.isInfinite(MathUtils.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY)));
 
772
        assertEquals(Double.MIN_VALUE, MathUtils.nextAfter(0, 1), 0);
 
773
        assertEquals(-Double.MIN_VALUE, MathUtils.nextAfter(0, -1), 0);
 
774
        assertEquals(0, MathUtils.nextAfter(Double.MIN_VALUE, -1), 0);
 
775
        assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0);
 
776
    }
 
777
 
 
778
    public void testScalb() {
 
779
        assertEquals( 0.0, MathUtils.scalb(0.0, 5), 1.0e-15);
 
780
        assertEquals(32.0, MathUtils.scalb(1.0, 5), 1.0e-15);
 
781
        assertEquals(1.0 / 32.0, MathUtils.scalb(1.0,  -5), 1.0e-15);
 
782
        assertEquals(Math.PI, MathUtils.scalb(Math.PI, 0), 1.0e-15);
 
783
        assertTrue(Double.isInfinite(MathUtils.scalb(Double.POSITIVE_INFINITY, 1)));
 
784
        assertTrue(Double.isInfinite(MathUtils.scalb(Double.NEGATIVE_INFINITY, 1)));
 
785
        assertTrue(Double.isNaN(MathUtils.scalb(Double.NaN, 1)));
 
786
    }
 
787
 
 
788
    public void testNormalizeAngle() {
 
789
        for (double a = -15.0; a <= 15.0; a += 0.1) {
 
790
            for (double b = -15.0; b <= 15.0; b += 0.2) {
 
791
                double c = MathUtils.normalizeAngle(a, b);
 
792
                assertTrue((b - Math.PI) <= c);
 
793
                assertTrue(c <= (b + Math.PI));
 
794
                double twoK = Math.rint((a - c) / Math.PI);
 
795
                assertEquals(c, a - twoK * Math.PI, 1.0e-14);
 
796
            }
 
797
        }
 
798
    }
 
799
 
 
800
    public void testRoundDouble() {
 
801
        double x = 1.234567890;
 
802
        assertEquals(1.23, MathUtils.round(x, 2), 0.0);
 
803
        assertEquals(1.235, MathUtils.round(x, 3), 0.0);
 
804
        assertEquals(1.2346, MathUtils.round(x, 4), 0.0);
 
805
 
 
806
        // JIRA MATH-151
 
807
        assertEquals(39.25, MathUtils.round(39.245, 2), 0.0);
 
808
        assertEquals(39.24, MathUtils.round(39.245, 2, BigDecimal.ROUND_DOWN), 0.0);
 
809
        double xx = 39.0;
 
810
        xx = xx + 245d / 1000d;
 
811
        assertEquals(39.25, MathUtils.round(xx, 2), 0.0);
 
812
 
 
813
        // BZ 35904
 
814
        assertEquals(30.1d, MathUtils.round(30.095d, 2), 0.0d);
 
815
        assertEquals(30.1d, MathUtils.round(30.095d, 1), 0.0d);
 
816
        assertEquals(33.1d, MathUtils.round(33.095d, 1), 0.0d);
 
817
        assertEquals(33.1d, MathUtils.round(33.095d, 2), 0.0d);
 
818
        assertEquals(50.09d, MathUtils.round(50.085d, 2), 0.0d);
 
819
        assertEquals(50.19d, MathUtils.round(50.185d, 2), 0.0d);
 
820
        assertEquals(50.01d, MathUtils.round(50.005d, 2), 0.0d);
 
821
        assertEquals(30.01d, MathUtils.round(30.005d, 2), 0.0d);
 
822
        assertEquals(30.65d, MathUtils.round(30.645d, 2), 0.0d);
 
823
 
 
824
        assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
 
825
        assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
 
826
        assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
 
827
        assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
 
828
        assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
 
829
        assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
 
830
 
 
831
        assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
 
832
        assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
 
833
        assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
 
834
        assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
 
835
        assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
 
836
        assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
 
837
 
 
838
        assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
 
839
        assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
 
840
        assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
 
841
        assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
 
842
        assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
 
843
        assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
 
844
 
 
845
        assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
846
        assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
847
        assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
848
        assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
849
        assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
850
        assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
851
        assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
852
        assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
853
 
 
854
        assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
855
        assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
856
        assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
857
        assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
858
        assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
859
        assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
860
        assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
861
        assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
862
        assertEquals(1.236, MathUtils.round(1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
863
        assertEquals(-1.236, MathUtils.round(-1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
864
 
 
865
        assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
 
866
        assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
867
        assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
 
868
        assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
 
869
        assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
870
        assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
 
871
        assertEquals(1.235, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
872
        assertEquals(-1.235, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
873
 
 
874
        assertEquals(-1.23, MathUtils.round(-1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
 
875
        assertEquals(1.23, MathUtils.round(1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
 
876
 
 
877
        try {
 
878
            MathUtils.round(1.234, 2, BigDecimal.ROUND_UNNECESSARY);
 
879
            fail();
 
880
        } catch (ArithmeticException ex) {
 
881
            // success
 
882
        }
 
883
 
 
884
        assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0);
 
885
        assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0);
 
886
        assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0);
 
887
        assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
 
888
        assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
 
889
        assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
 
890
 
 
891
        try {
 
892
            MathUtils.round(1.234, 2, 1923);
 
893
            fail();
 
894
        } catch (IllegalArgumentException ex) {
 
895
            // success
 
896
        }
 
897
 
 
898
        // MATH-151
 
899
        assertEquals(39.25, MathUtils.round(39.245, 2, BigDecimal.ROUND_HALF_UP), 0.0);
 
900
 
 
901
        // special values
 
902
        TestUtils.assertEquals(Double.NaN, MathUtils.round(Double.NaN, 2), 0.0);
 
903
        assertEquals(0.0, MathUtils.round(0.0, 2), 0.0);
 
904
        assertEquals(Double.POSITIVE_INFINITY, MathUtils.round(Double.POSITIVE_INFINITY, 2), 0.0);
 
905
        assertEquals(Double.NEGATIVE_INFINITY, MathUtils.round(Double.NEGATIVE_INFINITY, 2), 0.0);
 
906
    }
 
907
 
 
908
    public void testRoundFloat() {
 
909
        float x = 1.234567890f;
 
910
        assertEquals(1.23f, MathUtils.round(x, 2), 0.0);
 
911
        assertEquals(1.235f, MathUtils.round(x, 3), 0.0);
 
912
        assertEquals(1.2346f, MathUtils.round(x, 4), 0.0);
 
913
 
 
914
        // BZ 35904
 
915
        assertEquals(30.1f, MathUtils.round(30.095f, 2), 0.0f);
 
916
        assertEquals(30.1f, MathUtils.round(30.095f, 1), 0.0f);
 
917
        assertEquals(50.09f, MathUtils.round(50.085f, 2), 0.0f);
 
918
        assertEquals(50.19f, MathUtils.round(50.185f, 2), 0.0f);
 
919
        assertEquals(50.01f, MathUtils.round(50.005f, 2), 0.0f);
 
920
        assertEquals(30.01f, MathUtils.round(30.005f, 2), 0.0f);
 
921
        assertEquals(30.65f, MathUtils.round(30.645f, 2), 0.0f);
 
922
 
 
923
        assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
 
924
        assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
 
925
        assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
 
926
        assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
 
927
        assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
 
928
        assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
 
929
 
 
930
        assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
 
931
        assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
 
932
        assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
 
933
        assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
 
934
        assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
 
935
        assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
 
936
 
 
937
        assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
 
938
        assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
 
939
        assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
 
940
        assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
 
941
        assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
 
942
        assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
 
943
 
 
944
        assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
945
        assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
946
        assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
947
        assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
948
        assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
949
        assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
950
        assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
951
        assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
 
952
 
 
953
        assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
954
        assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
955
        assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
956
        assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
957
        assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
958
        assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
959
        assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
960
        assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
961
        assertEquals(1.236f, MathUtils.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
962
        assertEquals(-1.236f, MathUtils.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
 
963
 
 
964
        assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
 
965
        assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
966
        assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
 
967
        assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
 
968
        assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
969
        assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
 
970
        assertEquals(1.235f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
971
        assertEquals(-1.235f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
 
972
 
 
973
        assertEquals(-1.23f, MathUtils.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
 
974
        assertEquals(1.23f, MathUtils.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
 
975
 
 
976
        try {
 
977
            MathUtils.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY);
 
978
            fail();
 
979
        } catch (ArithmeticException ex) {
 
980
            // success
 
981
        }
 
982
 
 
983
        assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0);
 
984
        assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0);
 
985
        assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0);
 
986
        assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
 
987
        assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
 
988
        assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
 
989
 
 
990
        try {
 
991
            MathUtils.round(1.234f, 2, 1923);
 
992
            fail();
 
993
        } catch (IllegalArgumentException ex) {
 
994
            // success
 
995
        }
 
996
 
 
997
        // special values
 
998
        TestUtils.assertEquals(Float.NaN, MathUtils.round(Float.NaN, 2), 0.0f);
 
999
        assertEquals(0.0f, MathUtils.round(0.0f, 2), 0.0f);
 
1000
        assertEquals(Float.POSITIVE_INFINITY, MathUtils.round(Float.POSITIVE_INFINITY, 2), 0.0f);
 
1001
        assertEquals(Float.NEGATIVE_INFINITY, MathUtils.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
 
1002
    }
 
1003
 
 
1004
    public void testSignByte() {
 
1005
        assertEquals((byte) 1, MathUtils.sign((byte) 2));
 
1006
        assertEquals((byte) 0, MathUtils.sign((byte) 0));
 
1007
        assertEquals((byte) (-1), MathUtils.sign((byte) (-2)));
 
1008
    }
 
1009
 
 
1010
    public void testSignDouble() {
 
1011
        double delta = 0.0;
 
1012
        assertEquals(1.0, MathUtils.sign(2.0), delta);
 
1013
        assertEquals(0.0, MathUtils.sign(0.0), delta);
 
1014
        assertEquals(-1.0, MathUtils.sign(-2.0), delta);
 
1015
        TestUtils.assertSame(-0. / 0., MathUtils.sign(Double.NaN));
 
1016
    }
 
1017
 
 
1018
    public void testSignFloat() {
 
1019
        float delta = 0.0F;
 
1020
        assertEquals(1.0F, MathUtils.sign(2.0F), delta);
 
1021
        assertEquals(0.0F, MathUtils.sign(0.0F), delta);
 
1022
        assertEquals(-1.0F, MathUtils.sign(-2.0F), delta);
 
1023
        TestUtils.assertSame(Float.NaN, MathUtils.sign(Float.NaN));
 
1024
    }
 
1025
 
 
1026
    public void testSignInt() {
 
1027
        assertEquals(1, MathUtils.sign(2));
 
1028
        assertEquals(0, MathUtils.sign(0));
 
1029
        assertEquals((-1), MathUtils.sign((-2)));
 
1030
    }
 
1031
 
 
1032
    public void testSignLong() {
 
1033
        assertEquals(1L, MathUtils.sign(2L));
 
1034
        assertEquals(0L, MathUtils.sign(0L));
 
1035
        assertEquals(-1L, MathUtils.sign(-2L));
 
1036
    }
 
1037
 
 
1038
    public void testSignShort() {
 
1039
        assertEquals((short) 1, MathUtils.sign((short) 2));
 
1040
        assertEquals((short) 0, MathUtils.sign((short) 0));
 
1041
        assertEquals((short) (-1), MathUtils.sign((short) (-2)));
 
1042
    }
 
1043
 
 
1044
    public void testSinh() {
 
1045
        double x = 3.0;
 
1046
        double expected = 10.01787;
 
1047
        assertEquals(expected, MathUtils.sinh(x), 1.0e-5);
 
1048
    }
 
1049
 
 
1050
    public void testSinhNaN() {
 
1051
        assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN)));
 
1052
    }
 
1053
 
 
1054
    public void testSubAndCheck() {
 
1055
        int big = Integer.MAX_VALUE;
 
1056
        int bigNeg = Integer.MIN_VALUE;
 
1057
        assertEquals(big, MathUtils.subAndCheck(big, 0));
 
1058
        assertEquals(bigNeg + 1, MathUtils.subAndCheck(bigNeg, -1));
 
1059
        assertEquals(-1, MathUtils.subAndCheck(bigNeg, -big));
 
1060
        try {
 
1061
            MathUtils.subAndCheck(big, -1);
 
1062
            fail("Expecting ArithmeticException");
 
1063
        } catch (ArithmeticException ex) {
 
1064
        }
 
1065
        try {
 
1066
            MathUtils.subAndCheck(bigNeg, 1);
 
1067
            fail("Expecting ArithmeticException");
 
1068
        } catch (ArithmeticException ex) {
 
1069
        }
 
1070
    }
 
1071
 
 
1072
    public void testSubAndCheckErrorMessage() {
 
1073
        int big = Integer.MAX_VALUE;
 
1074
        try {
 
1075
            MathUtils.subAndCheck(big, -1);
 
1076
            fail("Expecting ArithmeticException");
 
1077
        } catch (ArithmeticException ex) {
 
1078
            assertEquals("overflow: subtract", ex.getMessage());
 
1079
        }
 
1080
    }
 
1081
 
 
1082
    public void testSubAndCheckLong() {
 
1083
        long max = Long.MAX_VALUE;
 
1084
        long min = Long.MIN_VALUE;
 
1085
        assertEquals(max, MathUtils.subAndCheck(max, 0));
 
1086
        assertEquals(min, MathUtils.subAndCheck(min, 0));
 
1087
        assertEquals(-max, MathUtils.subAndCheck(0, max));
 
1088
        assertEquals(min + 1, MathUtils.subAndCheck(min, -1));
 
1089
        // min == -1-max
 
1090
        assertEquals(-1, MathUtils.subAndCheck(-max - 1, -max));
 
1091
        assertEquals(max, MathUtils.subAndCheck(-1, -1 - max));
 
1092
        testSubAndCheckLongFailure(0L, min);
 
1093
        testSubAndCheckLongFailure(max, -1L);
 
1094
        testSubAndCheckLongFailure(min, 1L);
 
1095
    }
 
1096
 
 
1097
    private void testSubAndCheckLongFailure(long a, long b) {
 
1098
        try {
 
1099
            MathUtils.subAndCheck(a, b);
 
1100
            fail("Expecting ArithmeticException");
 
1101
        } catch (ArithmeticException ex) {
 
1102
            // success
 
1103
        }
 
1104
 
 
1105
    }
 
1106
 
 
1107
    public void testPow() {
 
1108
 
 
1109
        assertEquals(1801088541, MathUtils.pow(21, 7));
 
1110
        assertEquals(1, MathUtils.pow(21, 0));
 
1111
        try {
 
1112
            MathUtils.pow(21, -7);
 
1113
            fail("Expecting IllegalArgumentException");
 
1114
        } catch (IllegalArgumentException e) {
 
1115
            // expected behavior
 
1116
        }
 
1117
 
 
1118
        assertEquals(1801088541, MathUtils.pow(21, 7l));
 
1119
        assertEquals(1, MathUtils.pow(21, 0l));
 
1120
        try {
 
1121
            MathUtils.pow(21, -7l);
 
1122
            fail("Expecting IllegalArgumentException");
 
1123
        } catch (IllegalArgumentException e) {
 
1124
            // expected behavior
 
1125
        }
 
1126
 
 
1127
        assertEquals(1801088541l, MathUtils.pow(21l, 7));
 
1128
        assertEquals(1l, MathUtils.pow(21l, 0));
 
1129
        try {
 
1130
            MathUtils.pow(21l, -7);
 
1131
            fail("Expecting IllegalArgumentException");
 
1132
        } catch (IllegalArgumentException e) {
 
1133
            // expected behavior
 
1134
        }
 
1135
 
 
1136
        assertEquals(1801088541l, MathUtils.pow(21l, 7l));
 
1137
        assertEquals(1l, MathUtils.pow(21l, 0l));
 
1138
        try {
 
1139
            MathUtils.pow(21l, -7l);
 
1140
            fail("Expecting IllegalArgumentException");
 
1141
        } catch (IllegalArgumentException e) {
 
1142
            // expected behavior
 
1143
        }
 
1144
 
 
1145
        BigInteger twentyOne = BigInteger.valueOf(21l);
 
1146
        assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7));
 
1147
        assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0));
 
1148
        try {
 
1149
            MathUtils.pow(twentyOne, -7);
 
1150
            fail("Expecting IllegalArgumentException");
 
1151
        } catch (IllegalArgumentException e) {
 
1152
            // expected behavior
 
1153
        }
 
1154
 
 
1155
        assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7l));
 
1156
        assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0l));
 
1157
        try {
 
1158
            MathUtils.pow(twentyOne, -7l);
 
1159
            fail("Expecting IllegalArgumentException");
 
1160
        } catch (IllegalArgumentException e) {
 
1161
            // expected behavior
 
1162
        }
 
1163
 
 
1164
        assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, BigInteger.valueOf(7l)));
 
1165
        assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, BigInteger.ZERO));
 
1166
        try {
 
1167
            MathUtils.pow(twentyOne, BigInteger.valueOf(-7l));
 
1168
            fail("Expecting IllegalArgumentException");
 
1169
        } catch (IllegalArgumentException e) {
 
1170
            // expected behavior
 
1171
        }
 
1172
 
 
1173
        BigInteger bigOne =
 
1174
            new BigInteger("1543786922199448028351389769265814882661837148" +
 
1175
                           "4763915343722775611762713982220306372888519211" +
 
1176
                           "560905579993523402015636025177602059044911261");
 
1177
        assertEquals(bigOne, MathUtils.pow(twentyOne, 103));
 
1178
        assertEquals(bigOne, MathUtils.pow(twentyOne, 103l));
 
1179
        assertEquals(bigOne, MathUtils.pow(twentyOne, BigInteger.valueOf(103l)));
 
1180
        
 
1181
    }
 
1182
 
 
1183
    public void testL1DistanceDouble() {
 
1184
        double[] p1 = { 2.5,  0.0 };
 
1185
        double[] p2 = { -0.5, 4.0 };
 
1186
        assertEquals(7.0, MathUtils.distance1(p1, p2));
 
1187
    }
 
1188
 
 
1189
    public void testL1DistanceInt() {
 
1190
        int[] p1 = { 3, 0 };
 
1191
        int[] p2 = { 0, 4 };
 
1192
        assertEquals(7, MathUtils.distance1(p1, p2));
 
1193
    }
 
1194
 
 
1195
    public void testL2DistanceDouble() {
 
1196
        double[] p1 = { 2.5,  0.0 };
 
1197
        double[] p2 = { -0.5, 4.0 };
 
1198
        assertEquals(5.0, MathUtils.distance(p1, p2));
 
1199
    }
 
1200
 
 
1201
    public void testL2DistanceInt() {
 
1202
        int[] p1 = { 3, 0 };
 
1203
        int[] p2 = { 0, 4 };
 
1204
        assertEquals(5.0, MathUtils.distance(p1, p2));
 
1205
    }
 
1206
 
 
1207
    public void testLInfDistanceDouble() {
 
1208
        double[] p1 = { 2.5,  0.0 };
 
1209
        double[] p2 = { -0.5, 4.0 };
 
1210
        assertEquals(4.0, MathUtils.distanceInf(p1, p2));
 
1211
    }
 
1212
 
 
1213
    public void testLInfDistanceInt() {
 
1214
        int[] p1 = { 3, 0 };
 
1215
        int[] p2 = { 0, 4 };
 
1216
        assertEquals(4, MathUtils.distanceInf(p1, p2));
 
1217
    }
 
1218
 
 
1219
}