001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with this
004     * work for additional information regarding copyright ownership. The ASF
005     * licenses this file to You under the Apache License, Version 2.0 (the
006     * "License"); you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
009     * or agreed to in writing, software distributed under the License is
010     * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
011     * KIND, either express or implied. See the License for the specific language
012     * governing permissions and limitations under the License.
013     */
014    package org.apache.commons.math3.util;
015    
016    import java.math.BigDecimal;
017    import org.apache.commons.math3.exception.MathArithmeticException;
018    import org.apache.commons.math3.exception.MathIllegalArgumentException;
019    import org.apache.commons.math3.TestUtils;
020    
021    import org.junit.Assert;
022    import org.junit.Test;
023    
024    /**
025     * Test cases for the {@link Precision} class.
026     *
027     * @version $Id$
028     */
029    public class PrecisionTest {
030        @Test
031        public void testEqualsWithRelativeTolerance() {
032            Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 0d, 0d));
033            Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 1 / Double.NEGATIVE_INFINITY, 0d));
034    
035            final double eps = 1e-14;
036            Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654988, eps));
037            Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654987, eps));
038            Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654948, eps));
039            Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654949, eps));
040    
041            Assert.assertFalse(Precision.equalsWithRelativeTolerance(Precision.SAFE_MIN, 0.0, eps));
042    
043            Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.0000000000001e-300, 1e-300, eps));
044            Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.00000000000001e-300, 1e-300, eps));
045    
046            Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, 1.23, eps));
047            Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, 1.23, eps));
048    
049            Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, eps));
050            Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, eps));
051            Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, eps));
052    
053            Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, 1.23, eps));
054            Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, Double.NaN, eps));
055        }
056    
057        @Test
058        public void testEqualsIncludingNaN() {
059            double[] testArray = {
060                Double.NaN,
061                Double.POSITIVE_INFINITY,
062                Double.NEGATIVE_INFINITY,
063                1d,
064                0d };
065            for (int i = 0; i < testArray.length; i++) {
066                for (int j = 0; j < testArray.length; j++) {
067                    if (i == j) {
068                        Assert.assertTrue(Precision.equalsIncludingNaN(testArray[i], testArray[j]));
069                        Assert.assertTrue(Precision.equalsIncludingNaN(testArray[j], testArray[i]));
070                    } else {
071                        Assert.assertTrue(!Precision.equalsIncludingNaN(testArray[i], testArray[j]));
072                        Assert.assertTrue(!Precision.equalsIncludingNaN(testArray[j], testArray[i]));
073                    }
074                }
075            }
076        }
077    
078        @Test
079        public void testEqualsWithAllowedDelta() {
080            Assert.assertTrue(Precision.equals(153.0000, 153.0000, .0625));
081            Assert.assertTrue(Precision.equals(153.0000, 153.0625, .0625));
082            Assert.assertTrue(Precision.equals(152.9375, 153.0000, .0625));
083            Assert.assertFalse(Precision.equals(153.0000, 153.0625, .0624));
084            Assert.assertFalse(Precision.equals(152.9374, 153.0000, .0625));
085            Assert.assertFalse(Precision.equals(Double.NaN, Double.NaN, 1.0));
086            Assert.assertTrue(Precision.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
087            Assert.assertTrue(Precision.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0));
088            Assert.assertFalse(Precision.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
089        }
090    
091        @Test
092        public void testMath475() {
093            final double a = 1.7976931348623182E16;
094            final double b = FastMath.nextUp(a);
095    
096            double diff = FastMath.abs(a - b);
097            // Because they are adjacent floating point numbers, "a" and "b" are
098            // considered equal even though the allowed error is smaller than
099            // their difference.
100            Assert.assertTrue(Precision.equals(a, b, 0.5 * diff));
101    
102            final double c = FastMath.nextUp(b);
103            diff = FastMath.abs(a - c);
104            // Because "a" and "c" are not adjacent, the tolerance is taken into
105            // account for assessing equality.
106            Assert.assertTrue(Precision.equals(a, c, diff));
107            Assert.assertFalse(Precision.equals(a, c, (1 - 1e-16) * diff));
108        }
109    
110        @Test
111        public void testEqualsIncludingNaNWithAllowedDelta() {
112            Assert.assertTrue(Precision.equalsIncludingNaN(153.0000, 153.0000, .0625));
113            Assert.assertTrue(Precision.equalsIncludingNaN(153.0000, 153.0625, .0625));
114            Assert.assertTrue(Precision.equalsIncludingNaN(152.9375, 153.0000, .0625));
115            Assert.assertTrue(Precision.equalsIncludingNaN(Double.NaN, Double.NaN, 1.0));
116            Assert.assertTrue(Precision.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
117            Assert.assertTrue(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0));
118            Assert.assertFalse(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
119            Assert.assertFalse(Precision.equalsIncludingNaN(153.0000, 153.0625, .0624));
120            Assert.assertFalse(Precision.equalsIncludingNaN(152.9374, 153.0000, .0625));
121        }
122    
123        // Tests for floating point equality
124        @Test
125        public void testFloatEqualsWithAllowedUlps() {
126            Assert.assertTrue("+0.0f == -0.0f",Precision.equals(0.0f, -0.0f));
127            Assert.assertTrue("+0.0f == -0.0f (1 ulp)",Precision.equals(0.0f, -0.0f, 1));
128            float oneFloat = 1.0f;
129            Assert.assertTrue("1.0f == 1.0f + 1 ulp",Precision.equals(oneFloat, Float.intBitsToFloat(1 + Float.floatToIntBits(oneFloat))));
130            Assert.assertTrue("1.0f == 1.0f + 1 ulp (1 ulp)",Precision.equals(oneFloat, Float.intBitsToFloat(1 + Float.floatToIntBits(oneFloat)), 1));
131            Assert.assertFalse("1.0f != 1.0f + 2 ulp (1 ulp)",Precision.equals(oneFloat, Float.intBitsToFloat(2 + Float.floatToIntBits(oneFloat)), 1));
132    
133            Assert.assertTrue(Precision.equals(153.0f, 153.0f, 1));
134    
135            // These tests need adjusting for floating point precision
136    //        Assert.assertTrue(Precision.equals(153.0f, 153.00000000000003f, 1));
137    //        Assert.assertFalse(Precision.equals(153.0f, 153.00000000000006f, 1));
138    //        Assert.assertTrue(Precision.equals(153.0f, 152.99999999999997f, 1));
139    //        Assert.assertFalse(Precision.equals(153f, 152.99999999999994f, 1));
140    //
141    //        Assert.assertTrue(Precision.equals(-128.0f, -127.99999999999999f, 1));
142    //        Assert.assertFalse(Precision.equals(-128.0f, -127.99999999999997f, 1));
143    //        Assert.assertTrue(Precision.equals(-128.0f, -128.00000000000003f, 1));
144    //        Assert.assertFalse(Precision.equals(-128.0f, -128.00000000000006f, 1));
145    
146            Assert.assertTrue(Precision.equals(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, 1));
147            Assert.assertTrue(Precision.equals(Double.MAX_VALUE, Float.POSITIVE_INFINITY, 1));
148    
149            Assert.assertTrue(Precision.equals(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, 1));
150            Assert.assertTrue(Precision.equals(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY, 1));
151    
152            Assert.assertFalse(Precision.equals(Float.NaN, Float.NaN, 1));
153            Assert.assertFalse(Precision.equals(Float.NaN, Float.NaN, 0));
154            Assert.assertFalse(Precision.equals(Float.NaN, 0, 0));
155            Assert.assertFalse(Precision.equals(Float.NaN, Float.POSITIVE_INFINITY, 0));
156            Assert.assertFalse(Precision.equals(Float.NaN, Float.NEGATIVE_INFINITY, 0));
157    
158            Assert.assertFalse(Precision.equals(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, 100000));
159        }
160    
161        @Test
162        public void testEqualsWithAllowedUlps() {
163            Assert.assertTrue(Precision.equals(0.0, -0.0, 1));
164    
165            Assert.assertTrue(Precision.equals(1.0, 1 + FastMath.ulp(1d), 1));
166            Assert.assertFalse(Precision.equals(1.0, 1 + 2 * FastMath.ulp(1d), 1));
167    
168            final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY);
169            final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY);
170            Assert.assertTrue(Precision.equals(1.0, nUp1, 1));
171            Assert.assertTrue(Precision.equals(nUp1, nnUp1, 1));
172            Assert.assertFalse(Precision.equals(1.0, nnUp1, 1));
173    
174            Assert.assertTrue(Precision.equals(0.0, FastMath.ulp(0d), 1));
175            Assert.assertTrue(Precision.equals(0.0, -FastMath.ulp(0d), 1));
176    
177            Assert.assertTrue(Precision.equals(153.0, 153.0, 1));
178    
179            Assert.assertTrue(Precision.equals(153.0, 153.00000000000003, 1));
180            Assert.assertFalse(Precision.equals(153.0, 153.00000000000006, 1));
181            Assert.assertTrue(Precision.equals(153.0, 152.99999999999997, 1));
182            Assert.assertFalse(Precision.equals(153, 152.99999999999994, 1));
183    
184            Assert.assertTrue(Precision.equals(-128.0, -127.99999999999999, 1));
185            Assert.assertFalse(Precision.equals(-128.0, -127.99999999999997, 1));
186            Assert.assertTrue(Precision.equals(-128.0, -128.00000000000003, 1));
187            Assert.assertFalse(Precision.equals(-128.0, -128.00000000000006, 1));
188    
189            Assert.assertTrue(Precision.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
190            Assert.assertTrue(Precision.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
191    
192            Assert.assertTrue(Precision.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
193            Assert.assertTrue(Precision.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
194    
195            Assert.assertFalse(Precision.equals(Double.NaN, Double.NaN, 1));
196            Assert.assertFalse(Precision.equals(Double.NaN, Double.NaN, 0));
197            Assert.assertFalse(Precision.equals(Double.NaN, 0, 0));
198            Assert.assertFalse(Precision.equals(Double.NaN, Double.POSITIVE_INFINITY, 0));
199            Assert.assertFalse(Precision.equals(Double.NaN, Double.NEGATIVE_INFINITY, 0));
200    
201            Assert.assertFalse(Precision.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
202        }
203    
204        @Test
205        public void testEqualsIncludingNaNWithAllowedUlps() {
206            Assert.assertTrue(Precision.equalsIncludingNaN(0.0, -0.0, 1));
207    
208            Assert.assertTrue(Precision.equalsIncludingNaN(1.0, 1 + FastMath.ulp(1d), 1));
209            Assert.assertFalse(Precision.equalsIncludingNaN(1.0, 1 + 2 * FastMath.ulp(1d), 1));
210    
211            final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY);
212            final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY);
213            Assert.assertTrue(Precision.equalsIncludingNaN(1.0, nUp1, 1));
214            Assert.assertTrue(Precision.equalsIncludingNaN(nUp1, nnUp1, 1));
215            Assert.assertFalse(Precision.equalsIncludingNaN(1.0, nnUp1, 1));
216    
217            Assert.assertTrue(Precision.equalsIncludingNaN(0.0, FastMath.ulp(0d), 1));
218            Assert.assertTrue(Precision.equalsIncludingNaN(0.0, -FastMath.ulp(0d), 1));
219    
220            Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 153.0, 1));
221    
222            Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 153.00000000000003, 1));
223            Assert.assertFalse(Precision.equalsIncludingNaN(153.0, 153.00000000000006, 1));
224            Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 152.99999999999997, 1));
225            Assert.assertFalse(Precision.equalsIncludingNaN(153, 152.99999999999994, 1));
226    
227            Assert.assertTrue(Precision.equalsIncludingNaN(-128.0, -127.99999999999999, 1));
228            Assert.assertFalse(Precision.equalsIncludingNaN(-128.0, -127.99999999999997, 1));
229            Assert.assertTrue(Precision.equalsIncludingNaN(-128.0, -128.00000000000003, 1));
230            Assert.assertFalse(Precision.equalsIncludingNaN(-128.0, -128.00000000000006, 1));
231    
232            Assert.assertTrue(Precision.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
233            Assert.assertTrue(Precision.equalsIncludingNaN(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
234    
235            Assert.assertTrue(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
236            Assert.assertTrue(Precision.equalsIncludingNaN(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
237    
238            Assert.assertTrue(Precision.equalsIncludingNaN(Double.NaN, Double.NaN, 1));
239    
240            Assert.assertFalse(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
241        }
242    
243        @Test
244        public void testCompareToEpsilon() {
245            Assert.assertEquals(0, Precision.compareTo(152.33, 152.32, .011));
246            Assert.assertTrue(Precision.compareTo(152.308, 152.32, .011) < 0);
247            Assert.assertTrue(Precision.compareTo(152.33, 152.318, .011) > 0);
248            Assert.assertEquals(0, Precision.compareTo(Double.MIN_VALUE, +0.0, Double.MIN_VALUE));
249            Assert.assertEquals(0, Precision.compareTo(Double.MIN_VALUE, -0.0, Double.MIN_VALUE));
250        }
251    
252        @Test
253        public void testCompareToMaxUlps() {
254            double a     = 152.32;
255            double delta = FastMath.ulp(a);
256            for (int i = 0; i <= 10; ++i) {
257                if (i <= 5) {
258                    Assert.assertEquals( 0, Precision.compareTo(a, a + i * delta, 5));
259                    Assert.assertEquals( 0, Precision.compareTo(a, a - i * delta, 5));
260                } else {
261                    Assert.assertEquals(-1, Precision.compareTo(a, a + i * delta, 5));
262                    Assert.assertEquals(+1, Precision.compareTo(a, a - i * delta, 5));
263                }
264            }
265    
266            Assert.assertEquals( 0, Precision.compareTo(-0.0, 0.0, 0));
267    
268            Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, -0.0, 0));
269            Assert.assertEquals( 0, Precision.compareTo(-Double.MIN_VALUE, -0.0, 1));
270            Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, +0.0, 0));
271            Assert.assertEquals( 0, Precision.compareTo(-Double.MIN_VALUE, +0.0, 1));
272    
273            Assert.assertEquals(+1, Precision.compareTo( Double.MIN_VALUE, -0.0, 0));
274            Assert.assertEquals( 0, Precision.compareTo( Double.MIN_VALUE, -0.0, 1));
275            Assert.assertEquals(+1, Precision.compareTo( Double.MIN_VALUE, +0.0, 0));
276            Assert.assertEquals( 0, Precision.compareTo( Double.MIN_VALUE, +0.0, 1));
277    
278            Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, Double.MIN_VALUE, 0));
279            Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, Double.MIN_VALUE, 1));
280            Assert.assertEquals( 0, Precision.compareTo(-Double.MIN_VALUE, Double.MIN_VALUE, 2));
281    
282            Assert.assertEquals( 0, Precision.compareTo(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
283            Assert.assertEquals(-1, Precision.compareTo(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 0));
284    
285            Assert.assertEquals(+1, Precision.compareTo(Double.MAX_VALUE, Double.NaN, Integer.MAX_VALUE));
286            Assert.assertEquals(+1, Precision.compareTo(Double.NaN, Double.MAX_VALUE, Integer.MAX_VALUE));
287        }
288    
289        @Test
290        public void testRoundDouble() {
291            double x = 1.234567890;
292            Assert.assertEquals(1.23, Precision.round(x, 2), 0.0);
293            Assert.assertEquals(1.235, Precision.round(x, 3), 0.0);
294            Assert.assertEquals(1.2346, Precision.round(x, 4), 0.0);
295    
296            // JIRA MATH-151
297            Assert.assertEquals(39.25, Precision.round(39.245, 2), 0.0);
298            Assert.assertEquals(39.24, Precision.round(39.245, 2, BigDecimal.ROUND_DOWN), 0.0);
299            double xx = 39.0;
300            xx = xx + 245d / 1000d;
301            Assert.assertEquals(39.25, Precision.round(xx, 2), 0.0);
302    
303            // BZ 35904
304            Assert.assertEquals(30.1d, Precision.round(30.095d, 2), 0.0d);
305            Assert.assertEquals(30.1d, Precision.round(30.095d, 1), 0.0d);
306            Assert.assertEquals(33.1d, Precision.round(33.095d, 1), 0.0d);
307            Assert.assertEquals(33.1d, Precision.round(33.095d, 2), 0.0d);
308            Assert.assertEquals(50.09d, Precision.round(50.085d, 2), 0.0d);
309            Assert.assertEquals(50.19d, Precision.round(50.185d, 2), 0.0d);
310            Assert.assertEquals(50.01d, Precision.round(50.005d, 2), 0.0d);
311            Assert.assertEquals(30.01d, Precision.round(30.005d, 2), 0.0d);
312            Assert.assertEquals(30.65d, Precision.round(30.645d, 2), 0.0d);
313    
314            Assert.assertEquals(1.24, Precision.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
315            Assert.assertEquals(1.235, Precision.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
316            Assert.assertEquals(1.2346, Precision.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
317            Assert.assertEquals(-1.23, Precision.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
318            Assert.assertEquals(-1.234, Precision.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
319            Assert.assertEquals(-1.2345, Precision.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
320    
321            Assert.assertEquals(1.23, Precision.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
322            Assert.assertEquals(1.234, Precision.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
323            Assert.assertEquals(1.2345, Precision.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
324            Assert.assertEquals(-1.23, Precision.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
325            Assert.assertEquals(-1.234, Precision.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
326            Assert.assertEquals(-1.2345, Precision.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
327    
328            Assert.assertEquals(1.23, Precision.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
329            Assert.assertEquals(1.234, Precision.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
330            Assert.assertEquals(1.2345, Precision.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
331            Assert.assertEquals(-1.24, Precision.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
332            Assert.assertEquals(-1.235, Precision.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
333            Assert.assertEquals(-1.2346, Precision.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
334    
335            Assert.assertEquals(1.23, Precision.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
336            Assert.assertEquals(1.235, Precision.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
337            Assert.assertEquals(1.2346, Precision.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
338            Assert.assertEquals(-1.23, Precision.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
339            Assert.assertEquals(-1.235, Precision.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
340            Assert.assertEquals(-1.2346, Precision.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
341            Assert.assertEquals(1.234, Precision.round(1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
342            Assert.assertEquals(-1.234, Precision.round(-1.2345, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
343    
344            Assert.assertEquals(1.23, Precision.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
345            Assert.assertEquals(1.235, Precision.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
346            Assert.assertEquals(1.2346, Precision.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
347            Assert.assertEquals(-1.23, Precision.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
348            Assert.assertEquals(-1.235, Precision.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
349            Assert.assertEquals(-1.2346, Precision.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
350            Assert.assertEquals(1.234, Precision.round(1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
351            Assert.assertEquals(-1.234, Precision.round(-1.2345, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
352            Assert.assertEquals(1.236, Precision.round(1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
353            Assert.assertEquals(-1.236, Precision.round(-1.2355, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
354    
355            Assert.assertEquals(1.23, Precision.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
356            Assert.assertEquals(1.235, Precision.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
357            Assert.assertEquals(1.2346, Precision.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
358            Assert.assertEquals(-1.23, Precision.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
359            Assert.assertEquals(-1.235, Precision.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
360            Assert.assertEquals(-1.2346, Precision.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
361            Assert.assertEquals(1.235, Precision.round(1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0);
362            Assert.assertEquals(-1.235, Precision.round(-1.2345, 3, BigDecimal.ROUND_HALF_UP), 0.0);
363    
364            Assert.assertEquals(-1.23, Precision.round(-1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
365            Assert.assertEquals(1.23, Precision.round(1.23, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
366    
367            try {
368                Precision.round(1.234, 2, BigDecimal.ROUND_UNNECESSARY);
369                Assert.fail();
370            } catch (ArithmeticException ex) {
371                // expected
372            }
373    
374            Assert.assertEquals(1.24, Precision.round(x, 2, BigDecimal.ROUND_UP), 0.0);
375            Assert.assertEquals(1.235, Precision.round(x, 3, BigDecimal.ROUND_UP), 0.0);
376            Assert.assertEquals(1.2346, Precision.round(x, 4, BigDecimal.ROUND_UP), 0.0);
377            Assert.assertEquals(-1.24, Precision.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
378            Assert.assertEquals(-1.235, Precision.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
379            Assert.assertEquals(-1.2346, Precision.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
380    
381            try {
382                Precision.round(1.234, 2, 1923);
383                Assert.fail();
384            } catch (IllegalArgumentException ex) {
385                // expected
386            }
387    
388            // MATH-151
389            Assert.assertEquals(39.25, Precision.round(39.245, 2, BigDecimal.ROUND_HALF_UP), 0.0);
390    
391            // special values
392            TestUtils.assertEquals(Double.NaN, Precision.round(Double.NaN, 2), 0.0);
393            Assert.assertEquals(0.0, Precision.round(0.0, 2), 0.0);
394            Assert.assertEquals(Double.POSITIVE_INFINITY, Precision.round(Double.POSITIVE_INFINITY, 2), 0.0);
395            Assert.assertEquals(Double.NEGATIVE_INFINITY, Precision.round(Double.NEGATIVE_INFINITY, 2), 0.0);
396        }
397    
398        @Test
399        public void testRoundFloat() {
400            float x = 1.234567890f;
401            Assert.assertEquals(1.23f, Precision.round(x, 2), 0.0);
402            Assert.assertEquals(1.235f, Precision.round(x, 3), 0.0);
403            Assert.assertEquals(1.2346f, Precision.round(x, 4), 0.0);
404    
405            // BZ 35904
406            Assert.assertEquals(30.1f, Precision.round(30.095f, 2), 0.0f);
407            Assert.assertEquals(30.1f, Precision.round(30.095f, 1), 0.0f);
408            Assert.assertEquals(50.09f, Precision.round(50.085f, 2), 0.0f);
409            Assert.assertEquals(50.19f, Precision.round(50.185f, 2), 0.0f);
410            Assert.assertEquals(50.01f, Precision.round(50.005f, 2), 0.0f);
411            Assert.assertEquals(30.01f, Precision.round(30.005f, 2), 0.0f);
412            Assert.assertEquals(30.65f, Precision.round(30.645f, 2), 0.0f);
413    
414            Assert.assertEquals(1.24f, Precision.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
415            Assert.assertEquals(1.235f, Precision.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
416            Assert.assertEquals(1.2346f, Precision.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
417            Assert.assertEquals(-1.23f, Precision.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
418            Assert.assertEquals(-1.234f, Precision.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
419            Assert.assertEquals(-1.2345f, Precision.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
420    
421            Assert.assertEquals(1.23f, Precision.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
422            Assert.assertEquals(1.234f, Precision.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
423            Assert.assertEquals(1.2345f, Precision.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
424            Assert.assertEquals(-1.23f, Precision.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
425            Assert.assertEquals(-1.234f, Precision.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
426            Assert.assertEquals(-1.2345f, Precision.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
427    
428            Assert.assertEquals(1.23f, Precision.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
429            Assert.assertEquals(1.234f, Precision.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
430            Assert.assertEquals(1.2345f, Precision.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
431            Assert.assertEquals(-1.24f, Precision.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
432            Assert.assertEquals(-1.235f, Precision.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
433            Assert.assertEquals(-1.2346f, Precision.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
434    
435            Assert.assertEquals(1.23f, Precision.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
436            Assert.assertEquals(1.235f, Precision.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
437            Assert.assertEquals(1.2346f, Precision.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
438            Assert.assertEquals(-1.23f, Precision.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
439            Assert.assertEquals(-1.235f, Precision.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
440            Assert.assertEquals(-1.2346f, Precision.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
441            Assert.assertEquals(1.234f, Precision.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
442            Assert.assertEquals(-1.234f, Precision.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
443    
444            Assert.assertEquals(1.23f, Precision.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
445            Assert.assertEquals(1.235f, Precision.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
446            Assert.assertEquals(1.2346f, Precision.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
447            Assert.assertEquals(-1.23f, Precision.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
448            Assert.assertEquals(-1.235f, Precision.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
449            Assert.assertEquals(-1.2346f, Precision.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
450            Assert.assertEquals(1.234f, Precision.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
451            Assert.assertEquals(-1.234f, Precision.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
452            Assert.assertEquals(1.236f, Precision.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
453            Assert.assertEquals(-1.236f, Precision.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
454    
455            Assert.assertEquals(1.23f, Precision.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
456            Assert.assertEquals(1.235f, Precision.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
457            Assert.assertEquals(1.2346f, Precision.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
458            Assert.assertEquals(-1.23f, Precision.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
459            Assert.assertEquals(-1.235f, Precision.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
460            Assert.assertEquals(-1.2346f, Precision.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
461            Assert.assertEquals(1.235f, Precision.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
462            Assert.assertEquals(-1.235f, Precision.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
463    
464            Assert.assertEquals(-1.23f, Precision.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
465            Assert.assertEquals(1.23f, Precision.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
466    
467            try {
468                Precision.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY);
469                Assert.fail();
470            } catch (MathArithmeticException ex) {
471                // success
472            }
473    
474            Assert.assertEquals(1.24f, Precision.round(x, 2, BigDecimal.ROUND_UP), 0.0);
475            Assert.assertEquals(1.235f, Precision.round(x, 3, BigDecimal.ROUND_UP), 0.0);
476            Assert.assertEquals(1.2346f, Precision.round(x, 4, BigDecimal.ROUND_UP), 0.0);
477            Assert.assertEquals(-1.24f, Precision.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
478            Assert.assertEquals(-1.235f, Precision.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
479            Assert.assertEquals(-1.2346f, Precision.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
480    
481            try {
482                Precision.round(1.234f, 2, 1923);
483                Assert.fail();
484            } catch (MathIllegalArgumentException ex) {
485                // success
486            }
487    
488            // special values
489            TestUtils.assertEquals(Float.NaN, Precision.round(Float.NaN, 2), 0.0f);
490            Assert.assertEquals(0.0f, Precision.round(0.0f, 2), 0.0f);
491            Assert.assertEquals(Float.POSITIVE_INFINITY, Precision.round(Float.POSITIVE_INFINITY, 2), 0.0f);
492            Assert.assertEquals(Float.NEGATIVE_INFINITY, Precision.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
493        }
494    
495    
496        @Test
497        public void testIssue721() {
498            Assert.assertEquals(-53,   FastMath.getExponent(Precision.EPSILON));
499            Assert.assertEquals(-1022, FastMath.getExponent(Precision.SAFE_MIN));
500        }
501    
502    
503        @Test
504        public void testRepresentableDelta() {
505            int nonRepresentableCount = 0;
506            final double x = 100;
507            final int numTrials = 10000;
508            for (int i = 0; i < numTrials; i++) {
509                final double originalDelta = Math.random();
510                final double delta = Precision.representableDelta(x, originalDelta);
511                if (delta != originalDelta) {
512                    ++nonRepresentableCount;
513                }
514            }
515    
516            Assert.assertTrue(nonRepresentableCount / (double) numTrials > 0.9);
517        }
518    
519        @Test
520        public void testMath843() {
521            final double afterEpsilon = FastMath.nextAfter(Precision.EPSILON,
522                                                           Double.POSITIVE_INFINITY);
523    
524            // a) 1 + EPSILON is equal to 1.
525            Assert.assertTrue(1 + Precision.EPSILON == 1);
526    
527            // b) 1 + "the number after EPSILON" is not equal to 1.
528            Assert.assertFalse(1 + afterEpsilon == 1);
529        }
530    }