View Javadoc
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    * https://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.hipparchus.util;
15  
16  import java.math.RoundingMode;
17  
18  import org.hipparchus.UnitTestUtils;
19  import org.hipparchus.exception.MathRuntimeException;
20  import org.junit.Assert;
21  import org.junit.Test;
22  
23  /**
24   * Test cases for the {@link Precision} class.
25   */
26  public class PrecisionTest {
27      @Test
28      public void testEqualsWithRelativeTolerance() {
29          Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 0d, 0d));
30          Assert.assertTrue(Precision.equalsWithRelativeTolerance(0d, 1 / Double.NEGATIVE_INFINITY, 0d));
31  
32          final double eps = 1e-14;
33          Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654988, eps));
34          Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654987, eps));
35          Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654948, eps));
36          Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.987654687654968, 1.987654687654949, eps));
37  
38          Assert.assertFalse(Precision.equalsWithRelativeTolerance(Precision.SAFE_MIN, 0.0, eps));
39  
40          Assert.assertFalse(Precision.equalsWithRelativeTolerance(1.0000000000001e-300, 1e-300, eps));
41          Assert.assertTrue(Precision.equalsWithRelativeTolerance(1.00000000000001e-300, 1e-300, eps));
42  
43          Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, 1.23, eps));
44          Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, 1.23, eps));
45  
46          Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, eps));
47          Assert.assertTrue(Precision.equalsWithRelativeTolerance(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, eps));
48          Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, eps));
49  
50          Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, 1.23, eps));
51          Assert.assertFalse(Precision.equalsWithRelativeTolerance(Double.NaN, Double.NaN, eps));
52      }
53  
54      @Test
55      public void testEqualsIncludingNaN() {
56          double[] testArray = {
57              Double.NaN,
58              Double.POSITIVE_INFINITY,
59              Double.NEGATIVE_INFINITY,
60              1d,
61              0d };
62          for (int i = 0; i < testArray.length; i++) {
63              for (int j = 0; j < testArray.length; j++) {
64                  if (i == j) {
65                      Assert.assertTrue(Precision.equalsIncludingNaN(testArray[i], testArray[j]));
66                      Assert.assertTrue(Precision.equalsIncludingNaN(testArray[j], testArray[i]));
67                  } else {
68                      Assert.assertTrue(!Precision.equalsIncludingNaN(testArray[i], testArray[j]));
69                      Assert.assertTrue(!Precision.equalsIncludingNaN(testArray[j], testArray[i]));
70                  }
71              }
72          }
73      }
74  
75      @Test
76      public void testEqualsWithAllowedDelta() {
77          Assert.assertTrue(Precision.equals(153.0000, 153.0000, .0625));
78          Assert.assertTrue(Precision.equals(153.0000, 153.0625, .0625));
79          Assert.assertTrue(Precision.equals(152.9375, 153.0000, .0625));
80          Assert.assertFalse(Precision.equals(153.0000, 153.0625, .0624));
81          Assert.assertFalse(Precision.equals(152.9374, 153.0000, .0625));
82          Assert.assertFalse(Precision.equals(Double.NaN, Double.NaN, 1.0));
83          Assert.assertTrue(Precision.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
84          Assert.assertTrue(Precision.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0));
85          Assert.assertFalse(Precision.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
86      }
87  
88      @Test
89      public void testMath475() {
90          final double a = 1.7976931348623182E16;
91          final double b = FastMath.nextUp(a);
92  
93          double diff = FastMath.abs(a - b);
94          // Because they are adjacent floating point numbers, "a" and "b" are
95          // considered equal even though the allowed error is smaller than
96          // their difference.
97          Assert.assertTrue(Precision.equals(a, b, 0.5 * diff));
98  
99          final double c = FastMath.nextUp(b);
100         diff = FastMath.abs(a - c);
101         // Because "a" and "c" are not adjacent, the tolerance is taken into
102         // account for assessing equality.
103         Assert.assertTrue(Precision.equals(a, c, diff));
104         Assert.assertFalse(Precision.equals(a, c, (1 - 1e-16) * diff));
105     }
106 
107     @Test
108     public void testEqualsIncludingNaNWithAllowedDelta() {
109         Assert.assertTrue(Precision.equalsIncludingNaN(153.0000, 153.0000, .0625));
110         Assert.assertTrue(Precision.equalsIncludingNaN(153.0000, 153.0625, .0625));
111         Assert.assertTrue(Precision.equalsIncludingNaN(152.9375, 153.0000, .0625));
112         Assert.assertTrue(Precision.equalsIncludingNaN(Double.NaN, Double.NaN, 1.0));
113         Assert.assertTrue(Precision.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
114         Assert.assertTrue(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1.0));
115         Assert.assertFalse(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0));
116         Assert.assertFalse(Precision.equalsIncludingNaN(153.0000, 153.0625, .0624));
117         Assert.assertFalse(Precision.equalsIncludingNaN(152.9374, 153.0000, .0625));
118     }
119 
120     // Tests for floating point equality
121     @Test
122     public void testFloatEqualsWithAllowedUlps() {
123         Assert.assertTrue("+0.0f == -0.0f",Precision.equals(0.0f, -0.0f));
124         Assert.assertTrue("+0.0f == -0.0f (1 ulp)",Precision.equals(0.0f, -0.0f, 1));
125         float oneFloat = 1.0f;
126         Assert.assertTrue("1.0f == 1.0f + 1 ulp",Precision.equals(oneFloat, Float.intBitsToFloat(1 + Float.floatToIntBits(oneFloat))));
127         Assert.assertTrue("1.0f == 1.0f + 1 ulp (1 ulp)",Precision.equals(oneFloat, Float.intBitsToFloat(1 + Float.floatToIntBits(oneFloat)), 1));
128         Assert.assertFalse("1.0f != 1.0f + 2 ulp (1 ulp)",Precision.equals(oneFloat, Float.intBitsToFloat(2 + Float.floatToIntBits(oneFloat)), 1));
129 
130         Assert.assertTrue(Precision.equals(153.0f, 153.0f, 1));
131 
132         // These tests need adjusting for floating point precision
133 //        Assert.assertTrue(Precision.equals(153.0f, 153.00000000000003f, 1));
134 //        Assert.assertFalse(Precision.equals(153.0f, 153.00000000000006f, 1));
135 //        Assert.assertTrue(Precision.equals(153.0f, 152.99999999999997f, 1));
136 //        Assert.assertFalse(Precision.equals(153f, 152.99999999999994f, 1));
137 //
138 //        Assert.assertTrue(Precision.equals(-128.0f, -127.99999999999999f, 1));
139 //        Assert.assertFalse(Precision.equals(-128.0f, -127.99999999999997f, 1));
140 //        Assert.assertTrue(Precision.equals(-128.0f, -128.00000000000003f, 1));
141 //        Assert.assertFalse(Precision.equals(-128.0f, -128.00000000000006f, 1));
142 
143         Assert.assertTrue(Precision.equals(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, 1));
144         Assert.assertTrue(Precision.equals(Double.MAX_VALUE, Float.POSITIVE_INFINITY, 1));
145 
146         Assert.assertTrue(Precision.equals(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, 1));
147         Assert.assertTrue(Precision.equals(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY, 1));
148 
149         Assert.assertFalse(Precision.equals(Float.NaN, Float.NaN, 1));
150         Assert.assertFalse(Precision.equals(Float.NaN, Float.NaN, 0));
151         Assert.assertFalse(Precision.equals(Float.NaN, 0, 0));
152         Assert.assertFalse(Precision.equals(Float.NaN, Float.POSITIVE_INFINITY, 0));
153         Assert.assertFalse(Precision.equals(Float.NaN, Float.NEGATIVE_INFINITY, 0));
154 
155         Assert.assertFalse(Precision.equals(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, 100000));
156     }
157 
158     @Test
159     public void testEqualsWithAllowedUlps() {
160         Assert.assertTrue(Precision.equals(0.0, -0.0, 1));
161 
162         Assert.assertTrue(Precision.equals(1.0, 1 + FastMath.ulp(1d), 1));
163         Assert.assertFalse(Precision.equals(1.0, 1 + 2 * FastMath.ulp(1d), 1));
164 
165         final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY);
166         final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY);
167         Assert.assertTrue(Precision.equals(1.0, nUp1, 1));
168         Assert.assertTrue(Precision.equals(nUp1, nnUp1, 1));
169         Assert.assertFalse(Precision.equals(1.0, nnUp1, 1));
170 
171         Assert.assertTrue(Precision.equals(0.0, FastMath.ulp(0d), 1));
172         Assert.assertTrue(Precision.equals(0.0, -FastMath.ulp(0d), 1));
173 
174         Assert.assertTrue(Precision.equals(153.0, 153.0, 1));
175 
176         Assert.assertTrue(Precision.equals(153.0, 153.00000000000003, 1));
177         Assert.assertFalse(Precision.equals(153.0, 153.00000000000006, 1));
178         Assert.assertTrue(Precision.equals(153.0, 152.99999999999997, 1));
179         Assert.assertFalse(Precision.equals(153, 152.99999999999994, 1));
180 
181         Assert.assertTrue(Precision.equals(-128.0, -127.99999999999999, 1));
182         Assert.assertFalse(Precision.equals(-128.0, -127.99999999999997, 1));
183         Assert.assertTrue(Precision.equals(-128.0, -128.00000000000003, 1));
184         Assert.assertFalse(Precision.equals(-128.0, -128.00000000000006, 1));
185 
186         Assert.assertTrue(Precision.equals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
187         Assert.assertTrue(Precision.equals(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
188 
189         Assert.assertTrue(Precision.equals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
190         Assert.assertTrue(Precision.equals(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
191 
192         Assert.assertFalse(Precision.equals(Double.NaN, Double.NaN, 1));
193         Assert.assertFalse(Precision.equals(Double.NaN, Double.NaN, 0));
194         Assert.assertFalse(Precision.equals(Double.NaN, 0, 0));
195         Assert.assertFalse(Precision.equals(Double.NaN, Double.POSITIVE_INFINITY, 0));
196         Assert.assertFalse(Precision.equals(Double.NaN, Double.NEGATIVE_INFINITY, 0));
197 
198         Assert.assertFalse(Precision.equals(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
199     }
200 
201     @Test
202     public void testEqualsIncludingNaNWithAllowedUlps() {
203         Assert.assertTrue(Precision.equalsIncludingNaN(0.0, -0.0, 1));
204 
205         Assert.assertTrue(Precision.equalsIncludingNaN(1.0, 1 + FastMath.ulp(1d), 1));
206         Assert.assertFalse(Precision.equalsIncludingNaN(1.0, 1 + 2 * FastMath.ulp(1d), 1));
207 
208         final double nUp1 = FastMath.nextAfter(1d, Double.POSITIVE_INFINITY);
209         final double nnUp1 = FastMath.nextAfter(nUp1, Double.POSITIVE_INFINITY);
210         Assert.assertTrue(Precision.equalsIncludingNaN(1.0, nUp1, 1));
211         Assert.assertTrue(Precision.equalsIncludingNaN(nUp1, nnUp1, 1));
212         Assert.assertFalse(Precision.equalsIncludingNaN(1.0, nnUp1, 1));
213 
214         Assert.assertTrue(Precision.equalsIncludingNaN(0.0, FastMath.ulp(0d), 1));
215         Assert.assertTrue(Precision.equalsIncludingNaN(0.0, -FastMath.ulp(0d), 1));
216 
217         Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 153.0, 1));
218 
219         Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 153.00000000000003, 1));
220         Assert.assertFalse(Precision.equalsIncludingNaN(153.0, 153.00000000000006, 1));
221         Assert.assertTrue(Precision.equalsIncludingNaN(153.0, 152.99999999999997, 1));
222         Assert.assertFalse(Precision.equalsIncludingNaN(153, 152.99999999999994, 1));
223 
224         Assert.assertTrue(Precision.equalsIncludingNaN(-128.0, -127.99999999999999, 1));
225         Assert.assertFalse(Precision.equalsIncludingNaN(-128.0, -127.99999999999997, 1));
226         Assert.assertTrue(Precision.equalsIncludingNaN(-128.0, -128.00000000000003, 1));
227         Assert.assertFalse(Precision.equalsIncludingNaN(-128.0, -128.00000000000006, 1));
228 
229         Assert.assertTrue(Precision.equalsIncludingNaN(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 1));
230         Assert.assertTrue(Precision.equalsIncludingNaN(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
231 
232         Assert.assertTrue(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 1));
233         Assert.assertTrue(Precision.equalsIncludingNaN(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY, 1));
234 
235         Assert.assertTrue(Precision.equalsIncludingNaN(Double.NaN, Double.NaN, 1));
236 
237         Assert.assertFalse(Precision.equalsIncludingNaN(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100000));
238     }
239 
240     @Test
241     public void testCompareToEpsilon() {
242         Assert.assertEquals(0, Precision.compareTo(152.33, 152.32, .011));
243         Assert.assertTrue(Precision.compareTo(152.308, 152.32, .011) < 0);
244         Assert.assertTrue(Precision.compareTo(152.33, 152.318, .011) > 0);
245         Assert.assertEquals(0, Precision.compareTo(Double.MIN_VALUE, +0.0, Double.MIN_VALUE));
246         Assert.assertEquals(0, Precision.compareTo(Double.MIN_VALUE, -0.0, Double.MIN_VALUE));
247     }
248 
249     @Test
250     public void testCompareToMaxUlps() {
251         double a     = 152.32;
252         double delta = FastMath.ulp(a);
253         for (int i = 0; i <= 10; ++i) {
254             if (i <= 5) {
255                 Assert.assertEquals( 0, Precision.compareTo(a, a + i * delta, 5));
256                 Assert.assertEquals( 0, Precision.compareTo(a, a - i * delta, 5));
257             } else {
258                 Assert.assertEquals(-1, Precision.compareTo(a, a + i * delta, 5));
259                 Assert.assertEquals(+1, Precision.compareTo(a, a - i * delta, 5));
260             }
261         }
262 
263         Assert.assertEquals( 0, Precision.compareTo(-0.0, 0.0, 0));
264 
265         Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, -0.0, 0));
266         Assert.assertEquals( 0, Precision.compareTo(-Double.MIN_VALUE, -0.0, 1));
267         Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, +0.0, 0));
268         Assert.assertEquals( 0, Precision.compareTo(-Double.MIN_VALUE, +0.0, 1));
269 
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         Assert.assertEquals(+1, Precision.compareTo( Double.MIN_VALUE, +0.0, 0));
273         Assert.assertEquals( 0, Precision.compareTo( Double.MIN_VALUE, +0.0, 1));
274 
275         Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, Double.MIN_VALUE, 0));
276         Assert.assertEquals(-1, Precision.compareTo(-Double.MIN_VALUE, Double.MIN_VALUE, 1));
277         Assert.assertEquals( 0, Precision.compareTo(-Double.MIN_VALUE, Double.MIN_VALUE, 2));
278 
279         Assert.assertEquals( 0, Precision.compareTo(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1));
280         Assert.assertEquals(-1, Precision.compareTo(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 0));
281 
282         Assert.assertEquals(+1, Precision.compareTo(Double.MAX_VALUE, Double.NaN, Integer.MAX_VALUE));
283         Assert.assertEquals(+1, Precision.compareTo(Double.NaN, Double.MAX_VALUE, Integer.MAX_VALUE));
284     }
285 
286     @Test
287     public void testRoundDouble() {
288         double x = 1.234567890;
289         Assert.assertEquals(1.23, Precision.round(x, 2), 0.0);
290         Assert.assertEquals(1.235, Precision.round(x, 3), 0.0);
291         Assert.assertEquals(1.2346, Precision.round(x, 4), 0.0);
292 
293         // JIRA MATH-151
294         Assert.assertEquals(39.25, Precision.round(39.245, 2), 0.0);
295         Assert.assertEquals(39.24, Precision.round(39.245, 2, RoundingMode.DOWN), 0.0);
296         double xx = 39.0;
297         xx += 245d / 1000d;
298         Assert.assertEquals(39.25, Precision.round(xx, 2), 0.0);
299 
300         // BZ 35904
301         Assert.assertEquals(30.1d, Precision.round(30.095d, 2), 0.0d);
302         Assert.assertEquals(30.1d, Precision.round(30.095d, 1), 0.0d);
303         Assert.assertEquals(33.1d, Precision.round(33.095d, 1), 0.0d);
304         Assert.assertEquals(33.1d, Precision.round(33.095d, 2), 0.0d);
305         Assert.assertEquals(50.09d, Precision.round(50.085d, 2), 0.0d);
306         Assert.assertEquals(50.19d, Precision.round(50.185d, 2), 0.0d);
307         Assert.assertEquals(50.01d, Precision.round(50.005d, 2), 0.0d);
308         Assert.assertEquals(30.01d, Precision.round(30.005d, 2), 0.0d);
309         Assert.assertEquals(30.65d, Precision.round(30.645d, 2), 0.0d);
310 
311         Assert.assertEquals(1.24, Precision.round(x, 2, RoundingMode.CEILING), 0.0);
312         Assert.assertEquals(1.235, Precision.round(x, 3, RoundingMode.CEILING), 0.0);
313         Assert.assertEquals(1.2346, Precision.round(x, 4, RoundingMode.CEILING), 0.0);
314         Assert.assertEquals(-1.23, Precision.round(-x, 2, RoundingMode.CEILING), 0.0);
315         Assert.assertEquals(-1.234, Precision.round(-x, 3, RoundingMode.CEILING), 0.0);
316         Assert.assertEquals(-1.2345, Precision.round(-x, 4, RoundingMode.CEILING), 0.0);
317 
318         Assert.assertEquals(1.23, Precision.round(x, 2, RoundingMode.DOWN), 0.0);
319         Assert.assertEquals(1.234, Precision.round(x, 3, RoundingMode.DOWN), 0.0);
320         Assert.assertEquals(1.2345, Precision.round(x, 4, RoundingMode.DOWN), 0.0);
321         Assert.assertEquals(-1.23, Precision.round(-x, 2, RoundingMode.DOWN), 0.0);
322         Assert.assertEquals(-1.234, Precision.round(-x, 3, RoundingMode.DOWN), 0.0);
323         Assert.assertEquals(-1.2345, Precision.round(-x, 4, RoundingMode.DOWN), 0.0);
324 
325         Assert.assertEquals(1.23, Precision.round(x, 2, RoundingMode.FLOOR), 0.0);
326         Assert.assertEquals(1.234, Precision.round(x, 3, RoundingMode.FLOOR), 0.0);
327         Assert.assertEquals(1.2345, Precision.round(x, 4, RoundingMode.FLOOR), 0.0);
328         Assert.assertEquals(-1.24, Precision.round(-x, 2, RoundingMode.FLOOR), 0.0);
329         Assert.assertEquals(-1.235, Precision.round(-x, 3, RoundingMode.FLOOR), 0.0);
330         Assert.assertEquals(-1.2346, Precision.round(-x, 4, RoundingMode.FLOOR), 0.0);
331 
332         Assert.assertEquals(1.23, Precision.round(x, 2, RoundingMode.HALF_DOWN), 0.0);
333         Assert.assertEquals(1.235, Precision.round(x, 3, RoundingMode.HALF_DOWN), 0.0);
334         Assert.assertEquals(1.2346, Precision.round(x, 4, RoundingMode.HALF_DOWN), 0.0);
335         Assert.assertEquals(-1.23, Precision.round(-x, 2, RoundingMode.HALF_DOWN), 0.0);
336         Assert.assertEquals(-1.235, Precision.round(-x, 3, RoundingMode.HALF_DOWN), 0.0);
337         Assert.assertEquals(-1.2346, Precision.round(-x, 4, RoundingMode.HALF_DOWN), 0.0);
338         Assert.assertEquals(1.234, Precision.round(1.2345, 3, RoundingMode.HALF_DOWN), 0.0);
339         Assert.assertEquals(-1.234, Precision.round(-1.2345, 3, RoundingMode.HALF_DOWN), 0.0);
340 
341         Assert.assertEquals(1.23, Precision.round(x, 2, RoundingMode.HALF_EVEN), 0.0);
342         Assert.assertEquals(1.235, Precision.round(x, 3, RoundingMode.HALF_EVEN), 0.0);
343         Assert.assertEquals(1.2346, Precision.round(x, 4, RoundingMode.HALF_EVEN), 0.0);
344         Assert.assertEquals(-1.23, Precision.round(-x, 2, RoundingMode.HALF_EVEN), 0.0);
345         Assert.assertEquals(-1.235, Precision.round(-x, 3, RoundingMode.HALF_EVEN), 0.0);
346         Assert.assertEquals(-1.2346, Precision.round(-x, 4, RoundingMode.HALF_EVEN), 0.0);
347         Assert.assertEquals(1.234, Precision.round(1.2345, 3, RoundingMode.HALF_EVEN), 0.0);
348         Assert.assertEquals(-1.234, Precision.round(-1.2345, 3, RoundingMode.HALF_EVEN), 0.0);
349         Assert.assertEquals(1.236, Precision.round(1.2355, 3, RoundingMode.HALF_EVEN), 0.0);
350         Assert.assertEquals(-1.236, Precision.round(-1.2355, 3, RoundingMode.HALF_EVEN), 0.0);
351 
352         Assert.assertEquals(1.23, Precision.round(x, 2, RoundingMode.HALF_UP), 0.0);
353         Assert.assertEquals(1.235, Precision.round(x, 3, RoundingMode.HALF_UP), 0.0);
354         Assert.assertEquals(1.2346, Precision.round(x, 4, RoundingMode.HALF_UP), 0.0);
355         Assert.assertEquals(-1.23, Precision.round(-x, 2, RoundingMode.HALF_UP), 0.0);
356         Assert.assertEquals(-1.235, Precision.round(-x, 3, RoundingMode.HALF_UP), 0.0);
357         Assert.assertEquals(-1.2346, Precision.round(-x, 4, RoundingMode.HALF_UP), 0.0);
358         Assert.assertEquals(1.235, Precision.round(1.2345, 3, RoundingMode.HALF_UP), 0.0);
359         Assert.assertEquals(-1.235, Precision.round(-1.2345, 3, RoundingMode.HALF_UP), 0.0);
360 
361         Assert.assertEquals(-1.23, Precision.round(-1.23, 2, RoundingMode.UNNECESSARY), 0.0);
362         Assert.assertEquals(1.23, Precision.round(1.23, 2, RoundingMode.UNNECESSARY), 0.0);
363 
364         try {
365             Precision.round(1.234, 2, RoundingMode.UNNECESSARY);
366             Assert.fail();
367         } catch (ArithmeticException ex) {
368             // expected
369         }
370 
371         Assert.assertEquals(1.24, Precision.round(x, 2, RoundingMode.UP), 0.0);
372         Assert.assertEquals(1.235, Precision.round(x, 3, RoundingMode.UP), 0.0);
373         Assert.assertEquals(1.2346, Precision.round(x, 4, RoundingMode.UP), 0.0);
374         Assert.assertEquals(-1.24, Precision.round(-x, 2, RoundingMode.UP), 0.0);
375         Assert.assertEquals(-1.235, Precision.round(-x, 3, RoundingMode.UP), 0.0);
376         Assert.assertEquals(-1.2346, Precision.round(-x, 4, RoundingMode.UP), 0.0);
377 
378         // MATH-151
379         Assert.assertEquals(39.25, Precision.round(39.245, 2, RoundingMode.HALF_UP), 0.0);
380 
381         // special values
382         UnitTestUtils.assertEquals(Double.NaN, Precision.round(Double.NaN, 2), 0.0);
383         Assert.assertEquals(0.0, Precision.round(0.0, 2), 0.0);
384         Assert.assertEquals(Double.POSITIVE_INFINITY, Precision.round(Double.POSITIVE_INFINITY, 2), 0.0);
385         Assert.assertEquals(Double.NEGATIVE_INFINITY, Precision.round(Double.NEGATIVE_INFINITY, 2), 0.0);
386         // comparison of positive and negative zero is not possible -> always equal thus do string comparison
387         Assert.assertEquals("-0.0", Double.toString(Precision.round(-0.0, 0)));
388         Assert.assertEquals("-0.0", Double.toString(Precision.round(-1e-10, 0)));
389     }
390 
391     @Test
392     public void testRoundFloat() {
393         float x = 1.234567890f;
394         Assert.assertEquals(1.23f, Precision.round(x, 2), 0.0);
395         Assert.assertEquals(1.235f, Precision.round(x, 3), 0.0);
396         Assert.assertEquals(1.2346f, Precision.round(x, 4), 0.0);
397 
398         // BZ 35904
399         Assert.assertEquals(30.1f, Precision.round(30.095f, 2), 0.0f);
400         Assert.assertEquals(30.1f, Precision.round(30.095f, 1), 0.0f);
401         Assert.assertEquals(50.09f, Precision.round(50.085f, 2), 0.0f);
402         Assert.assertEquals(50.19f, Precision.round(50.185f, 2), 0.0f);
403         Assert.assertEquals(50.01f, Precision.round(50.005f, 2), 0.0f);
404         Assert.assertEquals(30.01f, Precision.round(30.005f, 2), 0.0f);
405         Assert.assertEquals(30.65f, Precision.round(30.645f, 2), 0.0f);
406 
407         Assert.assertEquals(1.24f, Precision.round(x, 2, RoundingMode.CEILING), 0.0);
408         Assert.assertEquals(1.235f, Precision.round(x, 3, RoundingMode.CEILING), 0.0);
409         Assert.assertEquals(1.2346f, Precision.round(x, 4, RoundingMode.CEILING), 0.0);
410         Assert.assertEquals(-1.23f, Precision.round(-x, 2, RoundingMode.CEILING), 0.0);
411         Assert.assertEquals(-1.234f, Precision.round(-x, 3, RoundingMode.CEILING), 0.0);
412         Assert.assertEquals(-1.2345f, Precision.round(-x, 4, RoundingMode.CEILING), 0.0);
413 
414         Assert.assertEquals(1.23f, Precision.round(x, 2, RoundingMode.DOWN), 0.0);
415         Assert.assertEquals(1.234f, Precision.round(x, 3, RoundingMode.DOWN), 0.0);
416         Assert.assertEquals(1.2345f, Precision.round(x, 4, RoundingMode.DOWN), 0.0);
417         Assert.assertEquals(-1.23f, Precision.round(-x, 2, RoundingMode.DOWN), 0.0);
418         Assert.assertEquals(-1.234f, Precision.round(-x, 3, RoundingMode.DOWN), 0.0);
419         Assert.assertEquals(-1.2345f, Precision.round(-x, 4, RoundingMode.DOWN), 0.0);
420 
421         Assert.assertEquals(1.23f, Precision.round(x, 2, RoundingMode.FLOOR), 0.0);
422         Assert.assertEquals(1.234f, Precision.round(x, 3, RoundingMode.FLOOR), 0.0);
423         Assert.assertEquals(1.2345f, Precision.round(x, 4, RoundingMode.FLOOR), 0.0);
424         Assert.assertEquals(-1.24f, Precision.round(-x, 2, RoundingMode.FLOOR), 0.0);
425         Assert.assertEquals(-1.235f, Precision.round(-x, 3, RoundingMode.FLOOR), 0.0);
426         Assert.assertEquals(-1.2346f, Precision.round(-x, 4, RoundingMode.FLOOR), 0.0);
427 
428         Assert.assertEquals(1.23f, Precision.round(x, 2, RoundingMode.HALF_DOWN), 0.0);
429         Assert.assertEquals(1.235f, Precision.round(x, 3, RoundingMode.HALF_DOWN), 0.0);
430         Assert.assertEquals(1.2346f, Precision.round(x, 4, RoundingMode.HALF_DOWN), 0.0);
431         Assert.assertEquals(-1.23f, Precision.round(-x, 2, RoundingMode.HALF_DOWN), 0.0);
432         Assert.assertEquals(-1.235f, Precision.round(-x, 3, RoundingMode.HALF_DOWN), 0.0);
433         Assert.assertEquals(-1.2346f, Precision.round(-x, 4, RoundingMode.HALF_DOWN), 0.0);
434         Assert.assertEquals(1.234f, Precision.round(1.2345f, 3, RoundingMode.HALF_DOWN), 0.0);
435         Assert.assertEquals(-1.234f, Precision.round(-1.2345f, 3, RoundingMode.HALF_DOWN), 0.0);
436 
437         Assert.assertEquals(1.23f, Precision.round(x, 2, RoundingMode.HALF_EVEN), 0.0);
438         Assert.assertEquals(1.235f, Precision.round(x, 3, RoundingMode.HALF_EVEN), 0.0);
439         Assert.assertEquals(1.2346f, Precision.round(x, 4, RoundingMode.HALF_EVEN), 0.0);
440         Assert.assertEquals(-1.23f, Precision.round(-x, 2, RoundingMode.HALF_EVEN), 0.0);
441         Assert.assertEquals(-1.235f, Precision.round(-x, 3, RoundingMode.HALF_EVEN), 0.0);
442         Assert.assertEquals(-1.2346f, Precision.round(-x, 4, RoundingMode.HALF_EVEN), 0.0);
443         Assert.assertEquals(1.234f, Precision.round(1.2345f, 3, RoundingMode.HALF_EVEN), 0.0);
444         Assert.assertEquals(-1.234f, Precision.round(-1.2345f, 3, RoundingMode.HALF_EVEN), 0.0);
445         Assert.assertEquals(1.236f, Precision.round(1.2355f, 3, RoundingMode.HALF_EVEN), 0.0);
446         Assert.assertEquals(-1.236f, Precision.round(-1.2355f, 3, RoundingMode.HALF_EVEN), 0.0);
447 
448         Assert.assertEquals(1.23f, Precision.round(x, 2, RoundingMode.HALF_UP), 0.0);
449         Assert.assertEquals(1.235f, Precision.round(x, 3, RoundingMode.HALF_UP), 0.0);
450         Assert.assertEquals(1.2346f, Precision.round(x, 4, RoundingMode.HALF_UP), 0.0);
451         Assert.assertEquals(-1.23f, Precision.round(-x, 2, RoundingMode.HALF_UP), 0.0);
452         Assert.assertEquals(-1.235f, Precision.round(-x, 3, RoundingMode.HALF_UP), 0.0);
453         Assert.assertEquals(-1.2346f, Precision.round(-x, 4, RoundingMode.HALF_UP), 0.0);
454         Assert.assertEquals(1.235f, Precision.round(1.2345f, 3, RoundingMode.HALF_UP), 0.0);
455         Assert.assertEquals(-1.235f, Precision.round(-1.2345f, 3, RoundingMode.HALF_UP), 0.0);
456 
457         Assert.assertEquals(-1.23f, Precision.round(-1.23f, 2, RoundingMode.UNNECESSARY), 0.0);
458         Assert.assertEquals(1.23f, Precision.round(1.23f, 2, RoundingMode.UNNECESSARY), 0.0);
459 
460         try {
461             Precision.round(1.234f, 2, RoundingMode.UNNECESSARY);
462             Assert.fail();
463         } catch (MathRuntimeException ex) {
464             // success
465         }
466 
467         Assert.assertEquals(1.24f, Precision.round(x, 2, RoundingMode.UP), 0.0);
468         Assert.assertEquals(1.235f, Precision.round(x, 3, RoundingMode.UP), 0.0);
469         Assert.assertEquals(1.2346f, Precision.round(x, 4, RoundingMode.UP), 0.0);
470         Assert.assertEquals(-1.24f, Precision.round(-x, 2, RoundingMode.UP), 0.0);
471         Assert.assertEquals(-1.235f, Precision.round(-x, 3, RoundingMode.UP), 0.0);
472         Assert.assertEquals(-1.2346f, Precision.round(-x, 4, RoundingMode.UP), 0.0);
473 
474         // special values
475         UnitTestUtils.assertEquals(Float.NaN, Precision.round(Float.NaN, 2), 0.0f);
476         Assert.assertEquals(0.0f, Precision.round(0.0f, 2), 0.0f);
477         Assert.assertEquals(Float.POSITIVE_INFINITY, Precision.round(Float.POSITIVE_INFINITY, 2), 0.0f);
478         Assert.assertEquals(Float.NEGATIVE_INFINITY, Precision.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
479         // comparison of positive and negative zero is not possible -> always equal thus do string comparison
480         Assert.assertEquals("-0.0", Float.toString(Precision.round(-0.0f, 0)));
481         Assert.assertEquals("-0.0", Float.toString(Precision.round(-1e-10f, 0)));
482 
483         // MATH-1070
484         Assert.assertEquals(0.0f, Precision.round(0f, 2, RoundingMode.UP), 0.0f);
485         Assert.assertEquals(0.05f, Precision.round(0.05f, 2, RoundingMode.UP), 0.0f);
486         Assert.assertEquals(0.06f, Precision.round(0.051f, 2, RoundingMode.UP), 0.0f);
487         Assert.assertEquals(0.06f, Precision.round(0.0505f, 2, RoundingMode.UP), 0.0f);
488         Assert.assertEquals(0.06f, Precision.round(0.059f, 2, RoundingMode.UP), 0.0f);
489     }
490 
491 
492     @Test
493     public void testIssue721() {
494         Assert.assertEquals(-53,   FastMath.getExponent(Precision.EPSILON));
495         Assert.assertEquals(-1022, FastMath.getExponent(Precision.SAFE_MIN));
496     }
497 
498 
499     @Test
500     public void testRepresentableDelta() {
501         int nonRepresentableCount = 0;
502         final double x = 100;
503         final int numTrials = 10000;
504         for (int i = 0; i < numTrials; i++) {
505             final double originalDelta = FastMath.random();
506             final double delta = Precision.representableDelta(x, originalDelta);
507             if (delta != originalDelta) {
508                 ++nonRepresentableCount;
509             }
510         }
511 
512         Assert.assertTrue(nonRepresentableCount / (double) numTrials > 0.9);
513     }
514 
515     @Test
516     public void testMath843() {
517         final double afterEpsilon = FastMath.nextAfter(Precision.EPSILON,
518                                                        Double.POSITIVE_INFINITY);
519 
520         // a) 1 + EPSILON is equal to 1.
521         Assert.assertTrue(1 + Precision.EPSILON == 1);
522 
523         // b) 1 + "the number after EPSILON" is not equal to 1.
524         Assert.assertFalse(1 + afterEpsilon == 1);
525     }
526 
527     @Test
528     public void testMath1127() {
529         Assert.assertFalse(Precision.equals(2.0, -2.0, 1));
530         Assert.assertTrue(Precision.equals(0.0, -0.0, 0));
531         Assert.assertFalse(Precision.equals(2.0f, -2.0f, 1));
532         Assert.assertTrue(Precision.equals(0.0f, -0.0f, 0));
533     }
534 
535     @Test
536     public void testIsMathematicalIntegerDouble() {
537 
538         Assert.assertFalse(Precision.isMathematicalInteger(Double.NaN));
539         Assert.assertFalse(Precision.isMathematicalInteger(Double.POSITIVE_INFINITY));
540         Assert.assertFalse(Precision.isMathematicalInteger(Double.NEGATIVE_INFINITY));
541         Assert.assertFalse(Precision.isMathematicalInteger(Double.MIN_NORMAL));
542         Assert.assertFalse(Precision.isMathematicalInteger(Double.MIN_VALUE));
543 
544         Assert.assertTrue(Precision.isMathematicalInteger(-0.0));
545         Assert.assertTrue(Precision.isMathematicalInteger(+0.0));
546 
547         for (int i = -1000; i < 1000; ++i) {
548             final double d = i;
549             Assert.assertTrue(Precision.isMathematicalInteger(d));
550             Assert.assertFalse(Precision.isMathematicalInteger(FastMath.nextAfter(d, Double.POSITIVE_INFINITY)));
551             Assert.assertFalse(Precision.isMathematicalInteger(FastMath.nextAfter(d, Double.NEGATIVE_INFINITY)));
552         }
553 
554         double minNoFractional = 0x1l << 52;
555         Assert.assertTrue(Precision.isMathematicalInteger(minNoFractional));
556         Assert.assertFalse(Precision.isMathematicalInteger(minNoFractional - 0.5));
557         Assert.assertTrue(Precision.isMathematicalInteger(minNoFractional + 0.5));
558 
559     }
560 
561     @Test
562     public void testIsMathematicalIntegerFloat() {
563 
564         Assert.assertFalse(Precision.isMathematicalInteger(Float.NaN));
565         Assert.assertFalse(Precision.isMathematicalInteger(Float.POSITIVE_INFINITY));
566         Assert.assertFalse(Precision.isMathematicalInteger(Float.NEGATIVE_INFINITY));
567         Assert.assertFalse(Precision.isMathematicalInteger(Float.MIN_NORMAL));
568         Assert.assertFalse(Precision.isMathematicalInteger(Float.MIN_VALUE));
569 
570         Assert.assertTrue(Precision.isMathematicalInteger(-0.0f));
571         Assert.assertTrue(Precision.isMathematicalInteger(+0.0f));
572 
573         for (int i = -1000; i < 1000; ++i) {
574             final float f = i;
575             Assert.assertTrue(Precision.isMathematicalInteger(f));
576             Assert.assertFalse(Precision.isMathematicalInteger(FastMath.nextAfter(f, Float.POSITIVE_INFINITY)));
577             Assert.assertFalse(Precision.isMathematicalInteger(FastMath.nextAfter(f, Float.NEGATIVE_INFINITY)));
578         }
579 
580         float minNoFractional = 0x1l << 23;
581         Assert.assertTrue(Precision.isMathematicalInteger(minNoFractional));
582         Assert.assertFalse(Precision.isMathematicalInteger(minNoFractional - 0.5f));
583         Assert.assertTrue(Precision.isMathematicalInteger(minNoFractional + 0.5f));
584 
585     }
586 
587 }