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
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.dfp;
24  
25  import org.junit.After;
26  import org.junit.Assert;
27  import org.junit.Before;
28  import org.junit.Test;
29  
30  public class DfpMathTest {
31  
32      private DfpField factory;
33      private Dfp pinf;
34      private Dfp ninf;
35      private Dfp nan;
36      private Dfp qnan;
37  
38      @Before
39      public void setUp() {
40          // Some basic setup.  Define some constants and clear the status flags
41          factory = new DfpField(20);
42          pinf = factory.newDfp("1").divide(factory.newDfp("0"));
43          ninf = factory.newDfp("-1").divide(factory.newDfp("0"));
44          nan = factory.newDfp("0").divide(factory.newDfp("0"));
45          qnan = factory.newDfp((byte)1, Dfp.QNAN);
46          ninf.getField().clearIEEEFlags();
47  
48          // force loading of dfpmath
49          Dfp pi = factory.getPi();
50          pi.getField().clearIEEEFlags();
51      }
52  
53      @After
54      public void tearDown() {
55          pinf = null;
56          ninf = null;
57          nan  = null;
58          qnan = null;
59      }
60  
61      // Generic test function.  Takes params x and y and tests them for
62      // equality.  Then checks the status flags against the flags argument.
63      // If the test fail, it prints the desc string
64      private void test(Dfp x, Dfp y, int flags, String desc)
65      {
66          boolean b = x.equals(y);
67  
68          if (!x.equals(y) && !x.unequal(y))  // NaNs involved
69              b = (x.toString().equals(y.toString()));
70  
71          if (x.equals(factory.newDfp("0")))  // distinguish +/- zero
72              b = (b && (x.toString().equals(y.toString())));
73  
74          b = (b && x.getField().getIEEEFlags() == flags);
75  
76          if (!b)
77              Assert.assertTrue("assersion failed "+desc+" x = "+x.toString()+" flags = "+x.getField().getIEEEFlags(), b);
78  
79          x.getField().clearIEEEFlags();
80      }
81  
82      @Test
83      public void testPow()
84      {
85          // Test special cases  exponent of zero
86          test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("0")),
87               factory.newDfp("1"),
88               0, "pow #1");
89  
90          test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-0")),
91               factory.newDfp("1"),
92               0, "pow #2");
93  
94          test(DfpMath.pow(factory.newDfp("2"), factory.newDfp("0")),
95               factory.newDfp("1"),
96               0, "pow #3");
97  
98          test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-0")),
99               factory.newDfp("1"),
100              0, "pow #4");
101 
102         test(DfpMath.pow(pinf, factory.newDfp("-0")),
103              factory.newDfp("1"),
104              0, "pow #5");
105 
106         test(DfpMath.pow(pinf, factory.newDfp("0")),
107              factory.newDfp("1"),
108              0, "pow #6");
109 
110         test(DfpMath.pow(ninf, factory.newDfp("-0")),
111              factory.newDfp("1"),
112              0, "pow #7");
113 
114         test(DfpMath.pow(ninf, factory.newDfp("0")),
115              factory.newDfp("1"),
116              0, "pow #8");
117 
118         test(DfpMath.pow(qnan, factory.newDfp("0")),
119              factory.newDfp("1"),
120              0, "pow #8");
121 
122         // exponent of one
123         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1")),
124              factory.newDfp("0"),
125              0, "pow #9");
126 
127         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1")),
128              factory.newDfp("-0"),
129              0, "pow #10");
130 
131         test(DfpMath.pow(factory.newDfp("2"), factory.newDfp("1")),
132              factory.newDfp("2"),
133              0, "pow #11");
134 
135         test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("1")),
136              factory.newDfp("-2"),
137              0, "pow #12");
138 
139         test(DfpMath.pow(pinf, factory.newDfp("1")),
140              pinf,
141              0, "pow #13");
142 
143         test(DfpMath.pow(ninf, factory.newDfp("1")),
144              ninf,
145              0, "pow #14");
146 
147         test(DfpMath.pow(qnan, factory.newDfp("1")),
148              qnan,
149              DfpField.FLAG_INVALID, "pow #14.1");
150 
151         // exponent of NaN
152         test(DfpMath.pow(factory.newDfp("0"), qnan),
153              qnan,
154              DfpField.FLAG_INVALID, "pow #15");
155 
156         test(DfpMath.pow(factory.newDfp("-0"), qnan),
157              qnan,
158              DfpField.FLAG_INVALID, "pow #16");
159 
160         test(DfpMath.pow(factory.newDfp("2"), qnan),
161              qnan,
162              DfpField.FLAG_INVALID, "pow #17");
163 
164         test(DfpMath.pow(factory.newDfp("-2"), qnan),
165              qnan,
166              DfpField.FLAG_INVALID, "pow #18");
167 
168         test(DfpMath.pow(pinf, qnan),
169              qnan,
170              DfpField.FLAG_INVALID, "pow #19");
171 
172         test(DfpMath.pow(ninf, qnan),
173              qnan,
174              DfpField.FLAG_INVALID, "pow #20");
175 
176         test(DfpMath.pow(qnan, qnan),
177              qnan,
178              DfpField.FLAG_INVALID, "pow #21");
179 
180         // radix of NaN
181         test(DfpMath.pow(qnan, factory.newDfp("1")),
182              qnan,
183              DfpField.FLAG_INVALID, "pow #22");
184 
185         test(DfpMath.pow(qnan, factory.newDfp("-1")),
186              qnan,
187              DfpField.FLAG_INVALID, "pow #23");
188 
189         test(DfpMath.pow(qnan, pinf),
190              qnan,
191              DfpField.FLAG_INVALID, "pow #24");
192 
193         test(DfpMath.pow(qnan, ninf),
194              qnan,
195              DfpField.FLAG_INVALID, "pow #25");
196 
197         test(DfpMath.pow(qnan, qnan),
198              qnan,
199              DfpField.FLAG_INVALID, "pow #26");
200 
201         // (x > 1) ^ pinf = pinf,    (x < -1) ^ pinf = pinf
202         test(DfpMath.pow(factory.newDfp("2"), pinf),
203              pinf,
204              0, "pow #27");
205 
206         test(DfpMath.pow(factory.newDfp("-2"), pinf),
207              pinf,
208              0, "pow #28");
209 
210         test(DfpMath.pow(pinf, pinf),
211              pinf,
212              0, "pow #29");
213 
214         test(DfpMath.pow(ninf, pinf),
215              pinf,
216              0, "pow #30");
217 
218         // (x > 1) ^ ninf = +0,    (x < -1) ^ ninf = +0
219         test(DfpMath.pow(factory.newDfp("2"), ninf),
220              factory.getZero(),
221              0, "pow #31");
222 
223         test(DfpMath.pow(factory.newDfp("-2"), ninf),
224              factory.getZero(),
225              0, "pow #32");
226 
227         test(DfpMath.pow(pinf, ninf),
228              factory.getZero(),
229              0, "pow #33");
230 
231         test(DfpMath.pow(ninf, ninf),
232              factory.getZero(),
233              0, "pow #34");
234 
235         // (-1 < x < 1) ^ pinf = 0
236         test(DfpMath.pow(factory.newDfp("0.5"), pinf),
237              factory.getZero(),
238              0, "pow #35");
239 
240         test(DfpMath.pow(factory.newDfp("-0.5"), pinf),
241              factory.getZero(),
242              0, "pow #36");
243 
244         // (-1 < x < 1) ^ ninf = pinf
245         test(DfpMath.pow(factory.newDfp("0.5"), ninf),
246              pinf,
247              0, "pow #37");
248 
249         test(DfpMath.pow(factory.newDfp("-0.5"), ninf),
250              pinf,
251              0, "pow #38");
252 
253         // +/- 1  ^ +/-inf  = NaN
254         test(DfpMath.pow(factory.getOne(), pinf),
255              qnan,
256              DfpField.FLAG_INVALID, "pow #39");
257 
258         test(DfpMath.pow(factory.getOne(), ninf),
259              qnan,
260              DfpField.FLAG_INVALID, "pow #40");
261 
262         test(DfpMath.pow(factory.newDfp("-1"), pinf),
263              qnan,
264              DfpField.FLAG_INVALID, "pow #41");
265 
266         test(DfpMath.pow(factory.getOne().negate(), ninf),
267              qnan,
268              DfpField.FLAG_INVALID, "pow #42");
269 
270         // +0  ^ +anything except 0, NAN  = +0
271 
272         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1")),
273              factory.newDfp("0"),
274              0, "pow #43");
275 
276         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1e30")),
277              factory.newDfp("0"),
278              0, "pow #44");
279 
280         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("1e-30")),
281              factory.newDfp("0"),
282              0, "pow #45");
283 
284         test(DfpMath.pow(factory.newDfp("0"), pinf),
285              factory.newDfp("0"),
286              0, "pow #46");
287 
288         // -0  ^ +anything except 0, NAN, odd integer  = +0
289 
290         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("2")),
291              factory.newDfp("0"),
292              0, "pow #47");
293 
294         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1e30")),
295              factory.newDfp("0"),
296              0, "pow #48");
297 
298         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("1e-30")),
299              factory.newDfp("0"),
300              DfpField.FLAG_INEXACT, "pow #49");
301 
302         test(DfpMath.pow(factory.newDfp("-0"), pinf),
303              factory.newDfp("0"),
304              0, "pow #50");
305 
306         // +0  ^ -anything except 0, NAN  = +INF
307 
308         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1")),
309              pinf,
310              0, "pow #51");
311 
312         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1e30")),
313              pinf,
314              0, "pow #52");
315 
316         test(DfpMath.pow(factory.newDfp("0"), factory.newDfp("-1e-30")),
317              pinf,
318              0, "pow #53");
319 
320         test(DfpMath.pow(factory.newDfp("0"), ninf),
321              pinf,
322              0, "pow #54");
323 
324         // -0  ^ -anything except 0, NAN, odd integer  = +INF
325 
326         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-2")),
327              pinf,
328              0, "pow #55");
329 
330         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1e30")),
331              pinf,
332              0, "pow #56");
333 
334         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1e-30")),
335              pinf,
336              DfpField.FLAG_INEXACT, "pow #57");
337 
338         test(DfpMath.pow(factory.newDfp("-0"), ninf),
339              pinf,
340              0, "pow #58");
341 
342         // -0  ^ -odd integer   =  -INF
343         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-1")),
344              ninf,
345              DfpField.FLAG_INEXACT, "pow #59");
346 
347         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("-12345")),
348              ninf,
349              DfpField.FLAG_INEXACT, "pow #60");
350 
351         // -0  ^ +odd integer   =  -0
352         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("3")),
353              factory.newDfp("-0"),
354              DfpField.FLAG_INEXACT, "pow #61");
355 
356         test(DfpMath.pow(factory.newDfp("-0"), factory.newDfp("12345")),
357              factory.newDfp("-0"),
358              DfpField.FLAG_INEXACT, "pow #62");
359 
360         // pinf  ^ +anything   = pinf
361         test(DfpMath.pow(pinf, factory.newDfp("3")),
362              pinf,
363              0, "pow #63");
364 
365         test(DfpMath.pow(pinf, factory.newDfp("1e30")),
366              pinf,
367              0, "pow #64");
368 
369         test(DfpMath.pow(pinf, factory.newDfp("1e-30")),
370              pinf,
371              0, "pow #65");
372 
373         test(DfpMath.pow(pinf, pinf),
374              pinf,
375              0, "pow #66");
376 
377         // pinf  ^ -anything   = +0
378 
379         test(DfpMath.pow(pinf, factory.newDfp("-3")),
380              factory.getZero(),
381              0, "pow #67");
382 
383         test(DfpMath.pow(pinf, factory.newDfp("-1e30")),
384              factory.getZero(),
385              0, "pow #68");
386 
387         test(DfpMath.pow(pinf, factory.newDfp("-1e-30")),
388              factory.getZero(),
389              0, "pow #69");
390 
391         test(DfpMath.pow(pinf, ninf),
392              factory.getZero(),
393              0, "pow #70");
394 
395         // ninf  ^ anything   = -0 ^ -anything
396         // ninf  ^ -anything except 0, NAN, odd integer  = +0
397 
398         test(DfpMath.pow(ninf, factory.newDfp("-2")),
399              factory.newDfp("0"),
400              0, "pow #71");
401 
402         test(DfpMath.pow(ninf, factory.newDfp("-1e30")),
403              factory.newDfp("0"),
404              0, "pow #72");
405 
406         test(DfpMath.pow(ninf, factory.newDfp("-1e-30")),
407              factory.newDfp("0"),
408              DfpField.FLAG_INEXACT, "pow #73");
409 
410         test(DfpMath.pow(ninf, ninf),
411              factory.newDfp("0"),
412              0, "pow #74");
413 
414         // ninf  ^ +anything except 0, NAN, odd integer  = +INF
415 
416         test(DfpMath.pow(ninf, factory.newDfp("2")),
417              pinf,
418              0, "pow #75");
419 
420         test(DfpMath.pow(ninf, factory.newDfp("1e30")),
421              pinf,
422              0, "pow #76");
423 
424         test(DfpMath.pow(ninf, factory.newDfp("1e-30")),
425              pinf,
426              DfpField.FLAG_INEXACT, "pow #77");
427 
428         test(DfpMath.pow(ninf, pinf),
429              pinf,
430              0, "pow #78");
431 
432         // ninf  ^ +odd integer   =  -INF
433         test(DfpMath.pow(ninf, factory.newDfp("3")),
434              ninf,
435              DfpField.FLAG_INEXACT, "pow #79");
436 
437         test(DfpMath.pow(ninf, factory.newDfp("12345")),
438              ninf,
439              DfpField.FLAG_INEXACT, "pow #80");
440 
441         // ninf  ^ -odd integer   =  -0
442         test(DfpMath.pow(ninf, factory.newDfp("-3")),
443              factory.newDfp("-0"),
444              DfpField.FLAG_INEXACT, "pow #81");
445 
446         test(DfpMath.pow(ninf, factory.newDfp("-12345")),
447              factory.newDfp("-0"),
448              DfpField.FLAG_INEXACT, "pow #82");
449 
450         // -anything ^ integer
451         test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("3")),
452              factory.newDfp("-8"),
453              DfpField.FLAG_INEXACT, "pow #83");
454 
455         test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("16")),
456              factory.newDfp("65536"),
457              0, "pow #84");
458 
459         test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-3")),
460              factory.newDfp("-0.125"),
461              DfpField.FLAG_INEXACT, "pow #85");
462 
463         test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-4")),
464              factory.newDfp("0.0625"),
465              0, "pow #86");
466 
467         // -anything ^ noninteger = NaN
468 
469         test(DfpMath.pow(factory.newDfp("-2"), factory.newDfp("-4.1")),
470              qnan,
471              DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "pow #87");
472 
473         // Some fractional cases.
474         test(DfpMath.pow(factory.newDfp("2"),factory.newDfp("1.5")),
475              factory.newDfp("2.8284271247461901"),
476              DfpField.FLAG_INEXACT, "pow #88");
477     }
478 
479     @Test
480     public void testSin()
481     {
482         test(DfpMath.sin(pinf),
483              nan,
484              DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "sin #1");
485 
486         test(DfpMath.sin(nan),
487              nan,
488              DfpField.FLAG_INVALID|DfpField.FLAG_INEXACT, "sin #2");
489 
490         test(DfpMath.sin(factory.getZero()),
491              factory.getZero(),
492              DfpField.FLAG_INEXACT, "sin #3");
493 
494         test(DfpMath.sin(factory.getPi()),
495              factory.getZero(),
496              DfpField.FLAG_INEXACT, "sin #4");
497 
498         test(DfpMath.sin(factory.getPi().negate()),
499              factory.newDfp("-0"),
500              DfpField.FLAG_INEXACT, "sin #5");
501 
502         test(DfpMath.sin(factory.getPi().multiply(2)),
503              factory.getZero(),
504              DfpField.FLAG_INEXACT, "sin #6");
505 
506         test(DfpMath.sin(factory.getPi().divide(2)),
507              factory.getOne(),
508              DfpField.FLAG_INEXACT, "sin #7");
509 
510         test(DfpMath.sin(factory.getPi().divide(2).negate()),
511              factory.getOne().negate(),
512              DfpField.FLAG_INEXACT, "sin #8");
513 
514         test(DfpMath.sin(DfpMath.atan(factory.getOne())),  // pi/4
515              factory.newDfp("0.5").sqrt(),
516              DfpField.FLAG_INEXACT, "sin #9");
517 
518         test(DfpMath.sin(DfpMath.atan(factory.getOne())).negate(),  // -pi/4
519              factory.newDfp("0.5").sqrt().negate(),
520              DfpField.FLAG_INEXACT, "sin #10");
521 
522         test(DfpMath.sin(DfpMath.atan(factory.getOne())).negate(),  // -pi/4
523              factory.newDfp("0.5").sqrt().negate(),
524              DfpField.FLAG_INEXACT, "sin #11");
525 
526         test(DfpMath.sin(factory.newDfp("0.1")),
527              factory.newDfp("0.0998334166468281523"),
528              DfpField.FLAG_INEXACT, "sin #12");
529 
530         test(DfpMath.sin(factory.newDfp("0.2")),
531              factory.newDfp("0.19866933079506121546"),
532              DfpField.FLAG_INEXACT, "sin #13");
533 
534         test(DfpMath.sin(factory.newDfp("0.3")),
535              factory.newDfp("0.2955202066613395751"),
536              DfpField.FLAG_INEXACT, "sin #14");
537 
538         test(DfpMath.sin(factory.newDfp("0.4")),
539              factory.newDfp("0.38941834230865049166"),
540              DfpField.FLAG_INEXACT, "sin #15");
541 
542         test(DfpMath.sin(factory.newDfp("0.5")),
543              factory.newDfp("0.47942553860420300026"),  // off by one ULP
544              DfpField.FLAG_INEXACT, "sin #16");
545 
546         test(DfpMath.sin(factory.newDfp("0.6")),
547              factory.newDfp("0.56464247339503535721"),  // off by one ULP
548              DfpField.FLAG_INEXACT, "sin #17");
549 
550         test(DfpMath.sin(factory.newDfp("0.7")),
551              factory.newDfp("0.64421768723769105367"),
552              DfpField.FLAG_INEXACT, "sin #18");
553 
554         test(DfpMath.sin(factory.newDfp("0.8")),
555              factory.newDfp("0.71735609089952276163"),
556              DfpField.FLAG_INEXACT, "sin #19");
557 
558         test(DfpMath.sin(factory.newDfp("0.9")),        // off by one ULP
559              factory.newDfp("0.78332690962748338847"),
560              DfpField.FLAG_INEXACT, "sin #20");
561 
562         test(DfpMath.sin(factory.newDfp("1.0")),
563              factory.newDfp("0.84147098480789650666"),
564              DfpField.FLAG_INEXACT, "sin #21");
565 
566         test(DfpMath.sin(factory.newDfp("1.1")),
567              factory.newDfp("0.89120736006143533995"),
568              DfpField.FLAG_INEXACT, "sin #22");
569 
570         test(DfpMath.sin(factory.newDfp("1.2")),
571              factory.newDfp("0.93203908596722634968"),
572              DfpField.FLAG_INEXACT, "sin #23");
573 
574         test(DfpMath.sin(factory.newDfp("1.3")),
575              factory.newDfp("0.9635581854171929647"),
576              DfpField.FLAG_INEXACT, "sin #24");
577 
578         test(DfpMath.sin(factory.newDfp("1.4")),
579              factory.newDfp("0.98544972998846018066"),
580              DfpField.FLAG_INEXACT, "sin #25");
581 
582         test(DfpMath.sin(factory.newDfp("1.5")),
583              factory.newDfp("0.99749498660405443096"),
584              DfpField.FLAG_INEXACT, "sin #26");
585 
586         test(DfpMath.sin(factory.newDfp("1.6")),
587              factory.newDfp("0.99957360304150516323"),
588              DfpField.FLAG_INEXACT, "sin #27");
589     }
590 
591 
592 }