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  package org.hipparchus.util;
23  
24  import org.hipparchus.CalculusFieldElement;
25  import org.hipparchus.Field;
26  import org.hipparchus.exception.MathIllegalArgumentException;
27  
28  /**
29   * This class wraps a {@code double} value in an object. It is similar to the
30   * standard class {@link Double}, while also implementing the
31   * {@link CalculusFieldElement} interface.
32   */
33  public class Binary64 extends Number implements CalculusFieldElement<Binary64>, Comparable<Binary64> {
34  
35      /** The constant value of {@code 0d} as a {@code Binary64}. */
36      public static final Binary64 ZERO;
37  
38      /** The constant value of {@code 1d} as a {@code Binary64}. */
39      public static final Binary64 ONE;
40  
41      /** The constant value of π as a {@code Binary64}. */
42      public static final Binary64 PI;
43  
44      /**
45       * The constant value of {@link Double#NEGATIVE_INFINITY} as a
46       * {@code Binary64}.
47       */
48      public static final Binary64 NEGATIVE_INFINITY;
49  
50      /**
51       * The constant value of {@link Double#POSITIVE_INFINITY} as a
52       * {@code Binary64}.
53       */
54      public static final Binary64 POSITIVE_INFINITY;
55  
56      /** The constant value of {@link Double#NaN} as a {@code Binary64}. */
57      public static final Binary64 NAN;
58  
59      /** */
60      private static final long serialVersionUID = 20120227L;
61  
62      static {
63          ZERO = new Binary64(0d);
64          ONE  = new Binary64(1d);
65          PI   = new Binary64(FastMath.PI);
66          NEGATIVE_INFINITY = new Binary64(Double.NEGATIVE_INFINITY);
67          POSITIVE_INFINITY = new Binary64(Double.POSITIVE_INFINITY);
68          NAN = new Binary64(Double.NaN);
69      }
70  
71      /** The primitive {@code double} value of this object. */
72      private final double value;
73  
74      /**
75       * Creates a new instance of this class.
76       *
77       * @param x the primitive {@code double} value of the object to be created
78       */
79      public Binary64(final double x) {
80          this.value = x;
81      }
82  
83      /*
84       * Methods from the FieldElement interface.
85       */
86  
87      /** {@inheritDoc} */
88      @Override
89      public Binary64 newInstance(final double v) {
90          return new Binary64(v);
91      }
92  
93      /** {@inheritDoc} */
94      @Override
95      public Field<Binary64> getField() {
96          return Binary64Field.getInstance();
97      }
98  
99      /**
100      * {@inheritDoc}
101      *
102      * The current implementation strictly enforces
103      * {@code this.add(a).equals(new Binary64(this.doubleValue()
104      * + a.doubleValue()))}.
105      */
106     @Override
107     public Binary64 add(final Binary64 a) {
108         return new Binary64(this.value + a.value);
109     }
110 
111     /**
112      * {@inheritDoc}
113      *
114      * The current implementation strictly enforces
115      * {@code this.subtract(a).equals(new Binary64(this.doubleValue()
116      * - a.doubleValue()))}.
117      */
118     @Override
119     public Binary64 subtract(final Binary64 a) {
120         return new Binary64(this.value - a.value);
121     }
122 
123     /**
124      * {@inheritDoc}
125      *
126      * The current implementation strictly enforces
127      * {@code this.negate().equals(new Binary64(-this.doubleValue()))}.
128      */
129     @Override
130     public Binary64 negate() {
131         return new Binary64(-this.value);
132     }
133 
134     @Override
135     public Binary64 square() {
136         return multiply(this);
137     }
138 
139     /**
140      * {@inheritDoc}
141      *
142      * The current implementation strictly enforces
143      * {@code this.multiply(a).equals(new Binary64(this.doubleValue()
144      * * a.doubleValue()))}.
145      */
146     @Override
147     public Binary64 multiply(final Binary64 a) {
148         return new Binary64(this.value * a.value);
149     }
150 
151     /**
152      * {@inheritDoc}
153      *
154      * The current implementation strictly enforces
155      * {@code this.multiply(n).equals(new Binary64(n * this.doubleValue()))}.
156      */
157     @Override
158     public Binary64 multiply(final int n) {
159         return new Binary64(n * this.value);
160     }
161 
162     /**
163      * {@inheritDoc}
164      *
165      * The current implementation strictly enforces
166      * {@code this.divide(a).equals(new Binary64(this.doubleValue()
167      * / a.doubleValue()))}.
168      *
169      */
170     @Override
171     public Binary64 divide(final Binary64 a) {
172         return new Binary64(this.value / a.value);
173     }
174 
175     /**
176      * {@inheritDoc}
177      *
178      * The current implementation strictly enforces
179      * {@code this.reciprocal().equals(new Binary64(1.0
180      * / this.doubleValue()))}.
181      */
182     @Override
183     public Binary64 reciprocal() {
184         return new Binary64(1.0 / this.value);
185     }
186 
187     /*
188      * Methods from the Number abstract class
189      */
190 
191     /**
192      * {@inheritDoc}
193      *
194      * The current implementation performs casting to a {@code byte}.
195      */
196     @Override
197     public byte byteValue() {
198         return (byte) value;
199     }
200 
201     /**
202      * {@inheritDoc}
203      *
204      * The current implementation performs casting to a {@code short}.
205      */
206     @Override
207     public short shortValue() {
208         return (short) value;
209     }
210 
211     /**
212      * {@inheritDoc}
213      *
214      * The current implementation performs casting to a {@code int}.
215      */
216     @Override
217     public int intValue() {
218         return (int) value;
219     }
220 
221     /**
222      * {@inheritDoc}
223      *
224      * The current implementation performs casting to a {@code long}.
225      */
226     @Override
227     public long longValue() {
228         return (long) value;
229     }
230 
231     /**
232      * {@inheritDoc}
233      *
234      * The current implementation performs casting to a {@code float}.
235      */
236     @Override
237     public float floatValue() {
238         return (float) value;
239     }
240 
241     /** {@inheritDoc} */
242     @Override
243     public double doubleValue() {
244         return value;
245     }
246 
247     /*
248      * Methods from the Comparable interface.
249      */
250 
251     /**
252      * {@inheritDoc}
253      *
254      * The current implementation returns the same value as
255      * {@code new Double(this.doubleValue()).compareTo(new
256      * Double(o.doubleValue()))}
257      *
258      * @see Double#compareTo(Double)
259      */
260     @Override
261     public int compareTo(final Binary64 o) {
262         return Double.compare(this.value, o.value);
263     }
264 
265     /*
266      * Methods from the Object abstract class.
267      */
268 
269     /** {@inheritDoc} */
270     @Override
271     public boolean equals(final Object obj) {
272         if (obj instanceof Binary64) {
273             final Binary64 that = (Binary64) obj;
274             return Double.doubleToLongBits(this.value) == Double
275                     .doubleToLongBits(that.value);
276         }
277         return false;
278     }
279 
280     /** {@inheritDoc}
281      * <p>
282      * This implementation considers +0.0 and -0.0 to be equal.
283      * </p>
284      * @since 1.8
285      */
286     @Override
287     public boolean isZero() {
288         return value == 0.0;
289     }
290 
291     /**
292      * {@inheritDoc}
293      *
294      * The current implementation returns the same value as
295      * {@code new Double(this.doubleValue()).hashCode()}
296      *
297      * @see Double#hashCode()
298      */
299     @Override
300     public int hashCode() {
301         long v = Double.doubleToLongBits(value);
302         return (int) (v ^ (v >>> 32));
303     }
304 
305     /**
306      * {@inheritDoc}
307      *
308      * The returned {@code String} is equal to
309      * {@code Double.toString(this.doubleValue())}
310      *
311      * @see Double#toString(double)
312      */
313     @Override
314     public String toString() {
315         return Double.toString(value);
316     }
317 
318     /*
319      * Methods inspired by the Double class.
320      */
321 
322     /**
323      * Returns {@code true} if {@code this} double precision number is infinite
324      * ({@link Double#POSITIVE_INFINITY} or {@link Double#NEGATIVE_INFINITY}).
325      *
326      * @return {@code true} if {@code this} number is infinite
327      */
328     @Override
329     public boolean isInfinite() {
330         return Double.isInfinite(value);
331     }
332 
333     /**
334      * Returns {@code true} if {@code this} double precision number is
335      * Not-a-Number ({@code NaN}), false otherwise.
336      *
337      * @return {@code true} if {@code this} is {@code NaN}
338      */
339     @Override
340     public boolean isNaN() {
341         return Double.isNaN(value);
342     }
343 
344     /** {@inheritDoc} */
345     @Override
346     public double getReal() {
347         return value;
348     }
349 
350     /** {@inheritDoc} */
351     @Override
352     public Binary64 add(final double a) {
353         return new Binary64(value + a);
354     }
355 
356     /** {@inheritDoc} */
357     @Override
358     public Binary64 subtract(final double a) {
359         return new Binary64(value - a);
360     }
361 
362     /** {@inheritDoc} */
363     @Override
364     public Binary64 multiply(final double a) {
365         return new Binary64(value * a);
366     }
367 
368     /** {@inheritDoc} */
369     @Override
370     public Binary64 divide(final double a) {
371         return new Binary64(value / a);
372     }
373 
374     /** {@inheritDoc} */
375     @Override
376     public Binary64 remainder(final double a) {
377         return new Binary64(FastMath.IEEEremainder(value, a));
378     }
379 
380     /** {@inheritDoc} */
381     @Override
382     public Binary64 remainder(final Binary64 a) {
383         return new Binary64(FastMath.IEEEremainder(value, a.value));
384     }
385 
386     /** {@inheritDoc} */
387     @Override
388     public Binary64 abs() {
389         return new Binary64(FastMath.abs(value));
390     }
391 
392     /** {@inheritDoc} */
393     @Override
394     public Binary64 ceil() {
395         return new Binary64(FastMath.ceil(value));
396     }
397 
398     /** {@inheritDoc} */
399     @Override
400     public Binary64 floor() {
401         return new Binary64(FastMath.floor(value));
402     }
403 
404     /** {@inheritDoc} */
405     @Override
406     public Binary64 rint() {
407         return new Binary64(FastMath.rint(value));
408     }
409 
410     /** {@inheritDoc} */
411     @Override
412     public Binary64 sign() {
413         return new Binary64(FastMath.signum(value));
414     }
415 
416     /** {@inheritDoc} */
417     @Override
418     public Binary64 copySign(final Binary64 sign) {
419         return new Binary64(FastMath.copySign(value, sign.value));
420     }
421 
422     /** {@inheritDoc} */
423     @Override
424     public Binary64 copySign(final double sign) {
425         return new Binary64(FastMath.copySign(value, sign));
426     }
427 
428     /** {@inheritDoc} */
429     @Override
430     public Binary64 scalb(final int n) {
431         return new Binary64(FastMath.scalb(value, n));
432     }
433 
434     /** {@inheritDoc} */
435     @Override
436     public Binary64 ulp() {
437         return new Binary64(FastMath.ulp(value));
438     }
439 
440     /** {@inheritDoc} */
441     @Override
442     public Binary64 hypot(final Binary64 y) {
443         return new Binary64(FastMath.hypot(value, y.value));
444     }
445 
446     /** {@inheritDoc} */
447     @Override
448     public Binary64 sqrt() {
449         return new Binary64(FastMath.sqrt(value));
450     }
451 
452     /** {@inheritDoc} */
453     @Override
454     public Binary64 cbrt() {
455         return new Binary64(FastMath.cbrt(value));
456     }
457 
458     /** {@inheritDoc} */
459     @Override
460     public Binary64 rootN(final int n) {
461         if (value < 0) {
462             return (n % 2 == 0) ? Binary64.NAN : new Binary64(-FastMath.pow(-value, 1.0 / n));
463         } else {
464             return new Binary64(FastMath.pow(value, 1.0 / n));
465         }
466     }
467 
468     /** {@inheritDoc} */
469     @Override
470     public Binary64 pow(final double p) {
471         return new Binary64(FastMath.pow(value, p));
472     }
473 
474     /** {@inheritDoc} */
475     @Override
476     public Binary64 pow(final int n) {
477         return new Binary64(FastMath.pow(value, n));
478     }
479 
480     /** {@inheritDoc} */
481     @Override
482     public Binary64 pow(final Binary64 e) {
483         return new Binary64(FastMath.pow(value, e.value));
484     }
485 
486     /** {@inheritDoc} */
487     @Override
488     public Binary64 exp() {
489         return new Binary64(FastMath.exp(value));
490     }
491 
492     /** {@inheritDoc} */
493     @Override
494     public Binary64 expm1() {
495         return new Binary64(FastMath.expm1(value));
496     }
497 
498     /** {@inheritDoc} */
499     @Override
500     public Binary64 log() {
501         return new Binary64(FastMath.log(value));
502     }
503 
504     /** {@inheritDoc} */
505     @Override
506     public Binary64 log1p() {
507         return new Binary64(FastMath.log1p(value));
508     }
509 
510     /** Base 10 logarithm.
511      * @return base 10 logarithm of the instance
512      */
513     @Override
514     public Binary64 log10() {
515         return new Binary64(FastMath.log10(value));
516     }
517 
518     /** {@inheritDoc} */
519     @Override
520     public Binary64 cos() {
521         return new Binary64(FastMath.cos(value));
522     }
523 
524     /** {@inheritDoc} */
525     @Override
526     public Binary64 sin() {
527         return new Binary64(FastMath.sin(value));
528     }
529 
530     /** {@inheritDoc} */
531     @Override
532     public FieldSinCos<Binary64> sinCos() {
533         final SinCos sc = FastMath.sinCos(value);
534         return new FieldSinCos<>(new Binary64(sc.sin()), new Binary64(sc.cos()));
535     }
536 
537     /** {@inheritDoc} */
538     @Override
539     public Binary64 tan() {
540         return new Binary64(FastMath.tan(value));
541     }
542 
543     /** {@inheritDoc} */
544     @Override
545     public Binary64 acos() {
546         return new Binary64(FastMath.acos(value));
547     }
548 
549     /** {@inheritDoc} */
550     @Override
551     public Binary64 asin() {
552         return new Binary64(FastMath.asin(value));
553     }
554 
555     /** {@inheritDoc} */
556     @Override
557     public Binary64 atan() {
558         return new Binary64(FastMath.atan(value));
559     }
560 
561     /** {@inheritDoc} */
562     @Override
563     public Binary64 atan2(final Binary64 x) {
564         return new Binary64(FastMath.atan2(value, x.value));
565     }
566 
567     /** {@inheritDoc} */
568     @Override
569     public Binary64 cosh() {
570         return new Binary64(FastMath.cosh(value));
571     }
572 
573     /** {@inheritDoc} */
574     @Override
575     public Binary64 sinh() {
576         return new Binary64(FastMath.sinh(value));
577     }
578 
579     /** {@inheritDoc} */
580     @Override
581     public FieldSinhCosh<Binary64> sinhCosh() {
582         final SinhCosh sch = FastMath.sinhCosh(value);
583         return new FieldSinhCosh<>(new Binary64(sch.sinh()), new Binary64(sch.cosh()));
584     }
585 
586     /** {@inheritDoc} */
587     @Override
588     public Binary64 tanh() {
589         return new Binary64(FastMath.tanh(value));
590     }
591 
592     /** {@inheritDoc} */
593     @Override
594     public Binary64 acosh() {
595         return new Binary64(FastMath.acosh(value));
596     }
597 
598     /** {@inheritDoc} */
599     @Override
600     public Binary64 asinh() {
601         return new Binary64(FastMath.asinh(value));
602     }
603 
604     /** {@inheritDoc} */
605     @Override
606     public Binary64 atanh() {
607         return new Binary64(FastMath.atanh(value));
608     }
609 
610     /** {@inheritDoc} */
611     @Override
612     public Binary64 toDegrees() {
613         return new Binary64(FastMath.toDegrees(value));
614     }
615 
616     /** {@inheritDoc} */
617     @Override
618     public Binary64 toRadians() {
619         return new Binary64(FastMath.toRadians(value));
620     }
621 
622     /** {@inheritDoc} */
623     @Override
624     public Binary64 linearCombination(final Binary64[] a, final Binary64[] b)
625         throws MathIllegalArgumentException {
626         MathUtils.checkDimension(a.length, b.length);
627         final double[] aDouble = new double[a.length];
628         final double[] bDouble = new double[b.length];
629         for (int i = 0; i < a.length; ++i) {
630             aDouble[i] = a[i].value;
631             bDouble[i] = b[i].value;
632         }
633         return new Binary64(MathArrays.linearCombination(aDouble, bDouble));
634     }
635 
636     /** {@inheritDoc} */
637     @Override
638     public Binary64 linearCombination(final double[] a, final Binary64[] b)
639         throws MathIllegalArgumentException {
640         MathUtils.checkDimension(a.length, b.length);
641         final double[] bDouble = new double[b.length];
642         for (int i = 0; i < a.length; ++i) {
643             bDouble[i] = b[i].value;
644         }
645         return new Binary64(MathArrays.linearCombination(a, bDouble));
646     }
647 
648     /** {@inheritDoc} */
649     @Override
650     public Binary64 linearCombination(final Binary64 a1, final Binary64 b1,
651                                        final Binary64 a2, final Binary64 b2) {
652         return new Binary64(MathArrays.linearCombination(a1.value, b1.value,
653                                                           a2.value, b2.value));
654     }
655 
656     /** {@inheritDoc} */
657     @Override
658     public Binary64 linearCombination(final double a1, final Binary64 b1,
659                                        final double a2, final Binary64 b2) {
660         return new Binary64(MathArrays.linearCombination(a1, b1.value,
661                                                           a2, b2.value));
662     }
663 
664     /** {@inheritDoc} */
665     @Override
666     public Binary64 linearCombination(final Binary64 a1, final Binary64 b1,
667                                        final Binary64 a2, final Binary64 b2,
668                                        final Binary64 a3, final Binary64 b3) {
669         return new Binary64(MathArrays.linearCombination(a1.value, b1.value,
670                                                           a2.value, b2.value,
671                                                           a3.value, b3.value));
672     }
673 
674     /** {@inheritDoc} */
675     @Override
676     public Binary64 linearCombination(final double a1, final Binary64 b1,
677                                        final double a2, final Binary64 b2,
678                                        final double a3, final Binary64 b3) {
679         return new Binary64(MathArrays.linearCombination(a1, b1.value,
680                                                           a2, b2.value,
681                                                           a3, b3.value));
682     }
683 
684     /** {@inheritDoc} */
685     @Override
686     public Binary64 linearCombination(final Binary64 a1, final Binary64 b1,
687                                        final Binary64 a2, final Binary64 b2,
688                                        final Binary64 a3, final Binary64 b3,
689                                        final Binary64 a4, final Binary64 b4) {
690         return new Binary64(MathArrays.linearCombination(a1.value, b1.value,
691                                                           a2.value, b2.value,
692                                                           a3.value, b3.value,
693                                                           a4.value, b4.value));
694     }
695 
696     /** {@inheritDoc} */
697     @Override
698     public Binary64 linearCombination(final double a1, final Binary64 b1,
699                                        final double a2, final Binary64 b2,
700                                        final double a3, final Binary64 b3,
701                                        final double a4, final Binary64 b4) {
702         return new Binary64(MathArrays.linearCombination(a1, b1.value,
703                                                           a2, b2.value,
704                                                           a3, b3.value,
705                                                           a4, b4.value));
706     }
707 
708     /** {@inheritDoc} */
709     @Override
710     public Binary64 getPi() {
711         return PI;
712     }
713 
714 }