1   /*
2    * Copyright 2003-2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.math.util;
17  
18  import java.math.BigDecimal;
19  
20  import org.apache.commons.math.TestUtils;
21  
22  import junit.framework.Test;
23  import junit.framework.TestCase;
24  import junit.framework.TestSuite;
25  
26  /**
27   * Test cases for the MathUtils class.
28   *
29   * @version $Revision: 321515 $ $Date: 2005-10-15 17:09:16 -0700 (Sat, 15 Oct 2005) $
30   */
31  public final class MathUtilsTest extends TestCase {
32  
33      public MathUtilsTest(String name) {
34          super(name);
35      }
36  
37      public static Test suite() {
38          TestSuite suite = new TestSuite(MathUtilsTest.class);
39          suite.setName("MathUtils Tests");
40          return suite;
41      }
42      
43      public void testAddAndCheck() {
44          int big = Integer.MAX_VALUE;
45          int bigNeg = Integer.MIN_VALUE;
46          assertEquals(big, MathUtils.addAndCheck(big, 0));
47          try {
48              int res = MathUtils.addAndCheck(big, 1);
49              fail("Expecting ArithmeticException");
50          } catch (ArithmeticException ex) {}
51          try {
52              int res = MathUtils.addAndCheck(bigNeg, -1);
53              fail("Expecting ArithmeticException");
54          } catch (ArithmeticException ex) {}
55      }
56      
57      public void testMulAndCheck() {
58          int big = Integer.MAX_VALUE;
59          int bigNeg = Integer.MIN_VALUE;
60          assertEquals(big, MathUtils.mulAndCheck(big, 1));
61          try {
62              int res = MathUtils.mulAndCheck(big, 2);
63              fail("Expecting ArithmeticException");
64          } catch (ArithmeticException ex) {}
65          try {
66              int res = MathUtils.mulAndCheck(bigNeg, 2);
67              fail("Expecting ArithmeticException");
68          } catch (ArithmeticException ex) {}
69      }
70      
71      public void testSubAndCheck() {
72          int big = Integer.MAX_VALUE;
73          int bigNeg = Integer.MIN_VALUE;
74          assertEquals(big, MathUtils.subAndCheck(big, 0));
75          try {
76              int res = MathUtils.subAndCheck(big, -1);
77              fail("Expecting ArithmeticException");
78          } catch (ArithmeticException ex) {}
79          try {
80              int res = MathUtils.subAndCheck(bigNeg, 1);
81              fail("Expecting ArithmeticException");
82          } catch (ArithmeticException ex) {}
83      }
84      
85      public void testSubAndCheckErrorMessage() {
86          int big = Integer.MAX_VALUE;
87          int bigNeg = Integer.MIN_VALUE;
88          try {
89              int res = MathUtils.subAndCheck(big, -1);
90              fail("Expecting ArithmeticException");
91          } catch (ArithmeticException ex) {
92              assertEquals("overflow: subtract", ex.getMessage());
93          }
94      }
95      
96      public void testBinomialCoefficient() {
97          long[] bcoef5 = {1,5,10,10,5,1};
98          long[] bcoef6 = {1,6,15,20,15,6,1};
99          for (int i = 0; i < 6; i++) {
100             assertEquals("5 choose " + i, bcoef5[i], 
101                 MathUtils.binomialCoefficient(5,i));
102         }
103         for (int i = 0; i < 7; i++) {
104             assertEquals("6 choose " + i, bcoef6[i], 
105                 MathUtils.binomialCoefficient(6,i));
106         }
107         
108         for (int n = 1; n < 10; n++) {
109             for (int k = 0; k <= n; k++) {
110                 assertEquals(n + " choose " + k, binomialCoefficient(n, k), 
111                     MathUtils.binomialCoefficient(n, k));
112                 assertEquals(n + " choose " + k,(double) binomialCoefficient(n, k), 
113                     MathUtils.binomialCoefficientDouble(n, k),Double.MIN_VALUE);
114                 assertEquals(n + " choose " + k,
115                     Math.log((double) binomialCoefficient(n, k)), 
116                     MathUtils.binomialCoefficientLog(n, k),10E-12);
117             }
118         }
119       
120       /* 
121        * Takes a long time for recursion to unwind, but succeeds 
122        * and yields exact value = 2,333,606,220
123         
124         assertEquals(MathUtils.binomialCoefficient(34,17),
125             binomialCoefficient(34,17));
126        */
127     }
128     
129     /** Verify that b(0,0) = 1 */
130     public void test0Choose0() {
131         assertEquals(MathUtils.binomialCoefficientDouble(0, 0), 1d, 0);
132         assertEquals(MathUtils.binomialCoefficientLog(0, 0), 0d, 0);
133         assertEquals(MathUtils.binomialCoefficient(0, 0), 1);
134     }
135     
136     public void testBinomialCoefficientFail() {
137         try {
138             long x = MathUtils.binomialCoefficient(4,5);
139             fail ("expecting IllegalArgumentException");
140         } catch (IllegalArgumentException ex) {
141             ;
142         }
143         
144         try {
145             double x = MathUtils.binomialCoefficientDouble(4,5);
146             fail ("expecting IllegalArgumentException");
147         } catch (IllegalArgumentException ex) {
148             ;
149         }
150         
151         try {
152             double x = MathUtils.binomialCoefficientLog(4,5);
153             fail ("expecting IllegalArgumentException");
154         } catch (IllegalArgumentException ex) {
155             ;
156         }
157         try {
158             long x = MathUtils.binomialCoefficient(67,34);
159             fail ("expecting ArithmeticException");
160         } catch (ArithmeticException ex) {
161             ;
162         }
163         double x = MathUtils.binomialCoefficientDouble(1030,515);
164         assertTrue("expecting infinite binomial coefficient",
165             Double.isInfinite(x));
166     }
167 
168     public void testFactorial() {
169         for (int i = 1; i < 10; i++) {
170             assertEquals(i + "! ",factorial(i),MathUtils.factorial(i));
171             assertEquals(i + "! ",(double)factorial(i),
172                 MathUtils.factorialDouble(i),Double.MIN_VALUE);
173             assertEquals(i + "! ",Math.log((double)factorial(i)),
174                 MathUtils.factorialLog(i),10E-12);
175         }
176         assertEquals("0", 1, MathUtils.factorial(0));
177         assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14);
178         assertEquals("0", 0.0d, MathUtils.factorialLog(0), 1E-14);
179     }
180 
181     public void testFactorialFail() {
182         try {
183             long x = MathUtils.factorial(-1);
184             fail ("expecting IllegalArgumentException");
185         } catch (IllegalArgumentException ex) {
186             ;
187         }
188         try {
189             double x = MathUtils.factorialDouble(-1);
190             fail ("expecting IllegalArgumentException");
191         } catch (IllegalArgumentException ex) {
192             ;
193         }
194         try {
195             double x = MathUtils.factorialLog(-1);
196             fail ("expecting IllegalArgumentException");
197         } catch (IllegalArgumentException ex) {
198             ;
199         }
200         try {
201             double x = MathUtils.factorial(21);
202             fail ("expecting ArithmeticException");
203         } catch (ArithmeticException ex) {
204             ;
205         }
206         assertTrue("expecting infinite factorial value",
207             Double.isInfinite(MathUtils.factorialDouble(171)));
208     }
209 
210 
211     /**
212      * Exact recursive implementation to test against
213      */
214     private long binomialCoefficient(int n, int k) {
215         if ((n == k) || (k == 0)) {
216             return 1;
217         }
218         if ((k == 1) || (k == n - 1)) {
219             return n;
220         }
221         return binomialCoefficient(n - 1, k - 1) +
222             binomialCoefficient(n - 1, k);
223     }
224 
225     /**
226      * Finds the largest values of n for which binomialCoefficient and
227      * binomialCoefficientDouble will return values that fit in a long, double,
228      * resp.  Remove comments around test below to get this in test-report
229      *
230         public void testLimits() {
231             findBinomialLimits();
232         }
233      */
234 
235     private void findBinomialLimits() {
236         /**
237          * will kick out 66 as the limit for long
238          */
239         boolean foundLimit = false;
240         int test = 10;
241         while (!foundLimit) {
242             try {
243                 double x = MathUtils.binomialCoefficient(test, test / 2);
244             } catch (ArithmeticException ex) {
245                 foundLimit = true;
246                 System.out.println
247                     ("largest n for binomialCoefficient = " + (test - 1) );
248             }
249             test++;
250         }
251 
252        /**
253         * will kick out 1029 as the limit for double
254         */
255         foundLimit = false;
256         test = 10;
257         while (!foundLimit) {
258             double x = MathUtils.binomialCoefficientDouble(test, test / 2);
259             if (Double.isInfinite(x)) {
260                 foundLimit = true;
261                 System.out.println
262                     ("largest n for binomialCoefficientD = " + (test - 1) );
263             }
264             test++;
265         }
266     }
267 
268     /**
269      * Finds the largest values of n for which factiorial and
270      * factorialDouble will return values that fit in a long, double,
271      * resp.  Remove comments around test below to get this in test-report
272 
273         public void testFactiorialLimits() {
274             findFactorialLimits();
275         }
276      */
277 
278     private void findFactorialLimits() {
279         /**
280          * will kick out 20 as the limit for long
281          */
282         boolean foundLimit = false;
283         int test = 10;
284         while (!foundLimit) {
285             try {
286                 double x = MathUtils.factorial(test);
287             } catch (ArithmeticException ex) {
288                 foundLimit = true;
289                 System.out.println
290                     ("largest n for factorial = " + (test - 1) );
291             }
292             test++;
293         }
294 
295        /**
296         * will kick out 170 as the limit for double
297         */
298         foundLimit = false;
299         test = 10;
300         while (!foundLimit) {
301             double x = MathUtils.factorialDouble(test);
302             if (Double.isInfinite(x)) {
303                 foundLimit = true;
304                 System.out.println
305                     ("largest n for factorialDouble = " + (test - 1) );
306             }
307             test++;
308         }
309     }
310 
311 
312     /**
313      * Exact direct multiplication implementation to test against
314      */
315     private long factorial(int n) {
316         long result = 1;
317         for (int i = 2; i <= n; i++) {
318             result *= i;
319         }
320         return result;
321     }
322 
323     public void testSignDouble() {
324         double delta = 0.0 ;
325         assertEquals( 1.0, MathUtils.indicator( 2.0 ), delta ) ;
326         assertEquals( -1.0, MathUtils.indicator( -2.0 ), delta ) ;
327     }
328 
329     public void testSignFloat() {
330         float delta = 0.0F ;
331         assertEquals( 1.0F, MathUtils.indicator( 2.0F ), delta ) ;
332         assertEquals( -1.0F, MathUtils.indicator( -2.0F ), delta ) ;
333     }
334 
335     public void testSignByte() {
336         assertEquals( (byte)1, MathUtils.indicator( (byte)2 ) ) ;
337         assertEquals( (byte)(-1), MathUtils.indicator( (byte)(-2) ) ) ;
338     }
339 
340     public void testSignShort() {
341         assertEquals( (short)1, MathUtils.indicator( (short)2 ) ) ;
342         assertEquals( (short)(-1), MathUtils.indicator( (short)(-2) ) ) ;
343     }
344 
345     public void testSignInt() {
346         assertEquals( (int)1, MathUtils.indicator( (int)(2) ) ) ;
347         assertEquals( (int)(-1), MathUtils.indicator( (int)(-2) ) ) ;
348     }
349 
350     public void testSignLong() {
351         assertEquals( 1L, MathUtils.indicator( 2L ) ) ;
352         assertEquals( -1L, MathUtils.indicator( -2L ) ) ;
353     }
354    
355     public void testIndicatorDouble() {
356         double delta = 0.0 ;
357         assertEquals( 1.0, MathUtils.indicator( 2.0 ), delta ) ;
358         assertEquals( 1.0, MathUtils.indicator( 0.0 ), delta ) ;
359         assertEquals( -1.0, MathUtils.indicator( -2.0 ), delta ) ;
360     }
361     
362     public void testIndicatorFloat() {
363         float delta = 0.0F ;
364         assertEquals( 1.0F, MathUtils.indicator( 2.0F ), delta ) ;
365         assertEquals( 1.0F, MathUtils.indicator( 0.0F ), delta ) ;
366         assertEquals( -1.0F, MathUtils.indicator( -2.0F ), delta ) ;
367     }
368     
369     public void testIndicatorByte() {
370         assertEquals( (byte)1, MathUtils.indicator( (byte)2 ) ) ;
371         assertEquals( (byte)1, MathUtils.indicator( (byte)0 ) ) ;
372         assertEquals( (byte)(-1), MathUtils.indicator( (byte)(-2) ) ) ;
373     }
374     
375     public void testIndicatorShort() {
376         assertEquals( (short)1, MathUtils.indicator( (short)2 ) ) ;
377         assertEquals( (short)1, MathUtils.indicator( (short)0 ) ) ;
378         assertEquals( (short)(-1), MathUtils.indicator( (short)(-2) ) ) ;
379     }
380     
381     public void testIndicatorInt() {
382         assertEquals( (int)1, MathUtils.indicator( (int)(2) ) ) ;
383         assertEquals( (int)1, MathUtils.indicator( (int)(0) ) ) ;
384         assertEquals( (int)(-1), MathUtils.indicator( (int)(-2) ) ) ;
385     }
386     
387     public void testIndicatorLong() {
388         assertEquals( 1L, MathUtils.indicator( 2L ) ) ;
389         assertEquals( 1L, MathUtils.indicator( 0L ) ) ;
390         assertEquals( -1L, MathUtils.indicator( -2L ) ) ;
391     }
392     
393     public void testCosh() {
394         double x = 3.0;
395         double expected = 10.06766;
396         assertEquals(expected, MathUtils.cosh(x), 1.0e-5);
397     }   
398     
399     public void testSinh() {
400         double x = 3.0;
401         double expected = 10.01787;
402         assertEquals(expected, MathUtils.sinh(x), 1.0e-5);
403     }   
404     
405     public void testCoshNaN() {
406         assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
407     }   
408     
409     public void testSinhNaN() {
410         assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN)));
411     } 
412     
413     public void testEquals() {
414         double[] testArray = {Double.NaN, Double.POSITIVE_INFINITY, 
415                 Double.NEGATIVE_INFINITY, 1d, 0d};
416         for (int i = 0; i < testArray.length; i++) {
417             for (int j = 0; j < testArray.length; j ++) {
418                 if (i == j) {
419                     assertTrue(MathUtils.equals(testArray[i], testArray[j]));
420                     assertTrue(MathUtils.equals(testArray[j], testArray[i]));
421                 } else {
422                     assertTrue(!MathUtils.equals(testArray[i], testArray[j]));
423                     assertTrue(!MathUtils.equals(testArray[j], testArray[i]));
424                 }
425             }
426         } 
427     }
428     
429     public void testHash() {
430         double[] testArray = {Double.NaN, Double.POSITIVE_INFINITY, 
431                 Double.NEGATIVE_INFINITY, 1d, 0d, 1E-14, (1 + 1E-14), 
432                 Double.MIN_VALUE, Double.MAX_VALUE};
433         for (int i = 0; i < testArray.length; i++) {
434             for (int j = 0; j < testArray.length; j ++) {
435                 if (i == j) {
436                     assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j]));
437                     assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i]));
438                 } else {
439                     assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j]));
440                     assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i]));
441                 }
442             }
443         } 
444     }
445     
446     public void testGcd() {
447         int a = 30;
448         int b = 50;
449         int c = 77;
450 
451         assertEquals(0, MathUtils.gcd(0, 0));
452         
453         assertEquals(b, MathUtils.gcd( 0,  b));
454         assertEquals(a, MathUtils.gcd( a,  0));
455         assertEquals(b, MathUtils.gcd( 0, -b));
456         assertEquals(a, MathUtils.gcd(-a,  0));
457         
458         assertEquals(10, MathUtils.gcd( a,  b));
459         assertEquals(10, MathUtils.gcd(-a,  b));
460         assertEquals(10, MathUtils.gcd( a, -b));
461         assertEquals(10, MathUtils.gcd(-a, -b));
462         
463         assertEquals(1, MathUtils.gcd( a,  c));
464         assertEquals(1, MathUtils.gcd(-a,  c));
465         assertEquals(1, MathUtils.gcd( a, -c));
466         assertEquals(1, MathUtils.gcd(-a, -c));
467     }
468     
469     public void testLcm() {
470         int a = 30;
471         int b = 50;
472         int c = 77;
473         
474         assertEquals(0, MathUtils.lcm(0, b));
475         assertEquals(0, MathUtils.lcm(a, 0));
476         assertEquals(b, MathUtils.lcm(1, b));
477         assertEquals(a, MathUtils.lcm(a, 1));
478         assertEquals(150, MathUtils.lcm(a, b));
479         assertEquals(150, MathUtils.lcm(-a, b));
480         assertEquals(150, MathUtils.lcm(a, -b));
481         assertEquals(2310, MathUtils.lcm(a, c));
482         
483         try {
484             MathUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
485             fail("Expecting ArithmeticException");
486         } catch (ArithmeticException ex) {
487             // expected
488         }
489     }
490     public void testRoundFloat() {
491         float x = 1.234567890f;
492         assertEquals(1.23f, MathUtils.round(x, 2), 0.0);
493         assertEquals(1.235f, MathUtils.round(x, 3), 0.0);
494         assertEquals(1.2346f, MathUtils.round(x, 4), 0.0);
495         
496         // BZ 35904
497         assertEquals(30.1f, MathUtils.round(30.095f, 2), 0.0f);
498         assertEquals(30.1f, MathUtils.round(30.095f, 1), 0.0f);
499         assertEquals(50.09f,  MathUtils.round(50.085f, 2), 0.0f);
500         assertEquals(50.19f,  MathUtils.round(50.185f, 2), 0.0f);
501         assertEquals(50.01f,  MathUtils.round(50.005f, 2), 0.0f);
502         assertEquals(30.01f,  MathUtils.round(30.005f, 2), 0.0f);
503         assertEquals(30.65f,  MathUtils.round(30.645f, 2), 0.0f);
504         
505         assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
506         assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
507         assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
508         assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
509         assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
510         assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
511 
512         assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
513         assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
514         assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
515         assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
516         assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
517         assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
518         
519         assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
520         assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
521         assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
522         assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
523         assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
524         assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
525         
526         assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
527         assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
528         assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
529         assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
530         assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
531         assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
532         assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
533         assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
534         
535         assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
536         assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
537         assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
538         assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
539         assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
540         assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
541         assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
542         assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
543         assertEquals(1.236f, MathUtils.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
544         assertEquals(-1.236f, MathUtils.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
545         
546         assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
547         assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
548         assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
549         assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
550         assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
551         assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
552         assertEquals(1.235f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
553         assertEquals(-1.235f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
554         
555         assertEquals(-1.23f, MathUtils.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
556         assertEquals(1.23f, MathUtils.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
557         
558         try {
559             MathUtils.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY);
560             fail();
561         } catch (ArithmeticException ex) {
562             // success
563         }
564         
565         assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0);
566         assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0);
567         assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0);
568         assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
569         assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
570         assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
571         
572         try {
573             MathUtils.round(1.234f, 2, 1923);
574             fail();
575         } catch (IllegalArgumentException ex) {
576             // success
577         }
578         
579         // special values
580         TestUtils.assertEquals(Float.NaN, MathUtils.round(Float.NaN, 2), 0.0f);
581         assertEquals(0.0f, MathUtils.round(0.0f, 2), 0.0f);
582         assertEquals(Float.POSITIVE_INFINITY, MathUtils.round(Float.POSITIVE_INFINITY, 2), 0.0f);
583         assertEquals(Float.NEGATIVE_INFINITY, MathUtils.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
584     }
585     
586     public void testRoundDouble() {
587         double x = 1.234567890;
588         assertEquals(1.23, MathUtils.round(x, 2), 0.0);
589         assertEquals(1.235, MathUtils.round(x, 3), 0.0);
590         assertEquals(1.2346, MathUtils.round(x, 4), 0.0);
591         
592         // BZ 35904
593         assertEquals(30.1d, MathUtils.round(30.095d, 2), 0.0d);
594         assertEquals(30.1d, MathUtils.round(30.095d, 1), 0.0d);
595         assertEquals(50.09d,  MathUtils.round(50.085d, 2), 0.0d);
596         assertEquals(50.19d,  MathUtils.round(50.185d, 2), 0.0d);
597         assertEquals(50.01d,  MathUtils.round(50.005d, 2), 0.0d);
598         assertEquals(30.01d,  MathUtils.round(30.005d, 2), 0.0d);
599         assertEquals(30.65d,  MathUtils.round(30.645d, 2), 0.0d);
600         
601         assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
602         assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
603         assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
604         assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
605         assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
606         assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
607 
608         assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
609         assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
610         assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
611         assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
612         assertEquals(-1.234, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
613         assertEquals(-1.2345, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
614         
615         assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
616         assertEquals(1.234, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
617         assertEquals(1.2345, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
618         assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
619         assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
620         assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
621         
622         assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
623         assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
624         assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
625         assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
626         assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
627         assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
628         assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
629         assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
630         
631         assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
632         assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
633         assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
634         assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
635         assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
636         assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
637         assertEquals(1.234, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
638         assertEquals(-1.234, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
639         assertEquals(1.236, MathUtils.round(1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
640         assertEquals(-1.236, MathUtils.round(-1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
641         
642         assertEquals(1.23, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
643         assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
644         assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
645         assertEquals(-1.23, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
646         assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
647         assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
648         assertEquals(1.235, MathUtils.round(1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0);
649         assertEquals(-1.235, MathUtils.round(-1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0);
650         
651         assertEquals(-1.23, MathUtils.round(-1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
652         assertEquals(1.23, MathUtils.round(1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
653         
654         try {
655             MathUtils.round(1.234, 2, BigDecimal.ROUND_UNNECESSARY);
656             fail();
657         } catch (ArithmeticException ex) {
658             // success
659         }
660         
661         assertEquals(1.24, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0);
662         assertEquals(1.235, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0);
663         assertEquals(1.2346, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0);
664         assertEquals(-1.24, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
665         assertEquals(-1.235, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
666         assertEquals(-1.2346, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
667         
668         try {
669             MathUtils.round(1.234, 2, 1923);
670             fail();
671         } catch (IllegalArgumentException ex) {
672             // success
673         }
674         
675         // special values
676         TestUtils.assertEquals(Double.NaN, MathUtils.round(Double.NaN, 2), 0.0);
677         assertEquals(0.0, MathUtils.round(0.0, 2), 0.0);
678         assertEquals(Double.POSITIVE_INFINITY, MathUtils.round(Double.POSITIVE_INFINITY, 2), 0.0);
679         assertEquals(Double.NEGATIVE_INFINITY, MathUtils.round(Double.NEGATIVE_INFINITY, 2), 0.0);
680     }
681 }