001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math3.util;
018
019import org.apache.commons.math3.RealFieldElement;
020import org.apache.commons.math3.Field;
021import org.apache.commons.math3.exception.DimensionMismatchException;
022
023/**
024 * This class wraps a {@code double} value in an object. It is similar to the
025 * standard class {@link Double}, while also implementing the
026 * {@link RealFieldElement} interface.
027 *
028 * @since 3.1
029 */
030public class Decimal64 extends Number
031                       implements RealFieldElement<Decimal64>, Comparable<Decimal64> {
032
033    /** The constant value of {@code 0d} as a {@code Decimal64}. */
034    public static final Decimal64 ZERO;
035
036    /** The constant value of {@code 1d} as a {@code Decimal64}. */
037    public static final Decimal64 ONE;
038
039    /**
040     * The constant value of {@link Double#NEGATIVE_INFINITY} as a
041     * {@code Decimal64}.
042     */
043    public static final Decimal64 NEGATIVE_INFINITY;
044
045    /**
046     * The constant value of {@link Double#POSITIVE_INFINITY} as a
047     * {@code Decimal64}.
048     */
049    public static final Decimal64 POSITIVE_INFINITY;
050
051    /** The constant value of {@link Double#NaN} as a {@code Decimal64}. */
052    public static final Decimal64 NAN;
053
054    /** */
055    private static final long serialVersionUID = 20120227L;
056
057    static {
058        ZERO = new Decimal64(0d);
059        ONE = new Decimal64(1d);
060        NEGATIVE_INFINITY = new Decimal64(Double.NEGATIVE_INFINITY);
061        POSITIVE_INFINITY = new Decimal64(Double.POSITIVE_INFINITY);
062        NAN = new Decimal64(Double.NaN);
063    }
064
065    /** The primitive {@code double} value of this object. */
066    private final double value;
067
068    /**
069     * Creates a new instance of this class.
070     *
071     * @param x the primitive {@code double} value of the object to be created
072     */
073    public Decimal64(final double x) {
074        this.value = x;
075    }
076
077    /*
078     * Methods from the FieldElement interface.
079     */
080
081    /** {@inheritDoc} */
082    public Field<Decimal64> getField() {
083        return Decimal64Field.getInstance();
084    }
085
086    /**
087     * {@inheritDoc}
088     *
089     * The current implementation strictly enforces
090     * {@code this.add(a).equals(new Decimal64(this.doubleValue()
091     * + a.doubleValue()))}.
092     */
093    public Decimal64 add(final Decimal64 a) {
094        return new Decimal64(this.value + a.value);
095    }
096
097    /**
098     * {@inheritDoc}
099     *
100     * The current implementation strictly enforces
101     * {@code this.subtract(a).equals(new Decimal64(this.doubleValue()
102     * - a.doubleValue()))}.
103     */
104    public Decimal64 subtract(final Decimal64 a) {
105        return new Decimal64(this.value - a.value);
106    }
107
108    /**
109     * {@inheritDoc}
110     *
111     * The current implementation strictly enforces
112     * {@code this.negate().equals(new Decimal64(-this.doubleValue()))}.
113     */
114    public Decimal64 negate() {
115        return new Decimal64(-this.value);
116    }
117
118    /**
119     * {@inheritDoc}
120     *
121     * The current implementation strictly enforces
122     * {@code this.multiply(a).equals(new Decimal64(this.doubleValue()
123     * * a.doubleValue()))}.
124     */
125    public Decimal64 multiply(final Decimal64 a) {
126        return new Decimal64(this.value * a.value);
127    }
128
129    /**
130     * {@inheritDoc}
131     *
132     * The current implementation strictly enforces
133     * {@code this.multiply(n).equals(new Decimal64(n * this.doubleValue()))}.
134     */
135    public Decimal64 multiply(final int n) {
136        return new Decimal64(n * this.value);
137    }
138
139    /**
140     * {@inheritDoc}
141     *
142     * The current implementation strictly enforces
143     * {@code this.divide(a).equals(new Decimal64(this.doubleValue()
144     * / a.doubleValue()))}.
145     *
146     */
147    public Decimal64 divide(final Decimal64 a) {
148        return new Decimal64(this.value / a.value);
149    }
150
151    /**
152     * {@inheritDoc}
153     *
154     * The current implementation strictly enforces
155     * {@code this.reciprocal().equals(new Decimal64(1.0
156     * / this.doubleValue()))}.
157     */
158    public Decimal64 reciprocal() {
159        return new Decimal64(1.0 / this.value);
160    }
161
162    /*
163     * Methods from the Number abstract class
164     */
165
166    /**
167     * {@inheritDoc}
168     *
169     * The current implementation performs casting to a {@code byte}.
170     */
171    @Override
172    public byte byteValue() {
173        return (byte) value;
174    }
175
176    /**
177     * {@inheritDoc}
178     *
179     * The current implementation performs casting to a {@code short}.
180     */
181    @Override
182    public short shortValue() {
183        return (short) value;
184    }
185
186    /**
187     * {@inheritDoc}
188     *
189     * The current implementation performs casting to a {@code int}.
190     */
191    @Override
192    public int intValue() {
193        return (int) value;
194    }
195
196    /**
197     * {@inheritDoc}
198     *
199     * The current implementation performs casting to a {@code long}.
200     */
201    @Override
202    public long longValue() {
203        return (long) value;
204    }
205
206    /**
207     * {@inheritDoc}
208     *
209     * The current implementation performs casting to a {@code float}.
210     */
211    @Override
212    public float floatValue() {
213        return (float) value;
214    }
215
216    /** {@inheritDoc} */
217    @Override
218    public double doubleValue() {
219        return value;
220    }
221
222    /*
223     * Methods from the Comparable interface.
224     */
225
226    /**
227     * {@inheritDoc}
228     *
229     * The current implementation returns the same value as
230     * <center> {@code new Double(this.doubleValue()).compareTo(new
231     * Double(o.doubleValue()))} </center>
232     *
233     * @see Double#compareTo(Double)
234     */
235    public int compareTo(final Decimal64 o) {
236        return Double.compare(this.value, o.value);
237    }
238
239    /*
240     * Methods from the Object abstract class.
241     */
242
243    /** {@inheritDoc} */
244    @Override
245    public boolean equals(final Object obj) {
246        if (obj instanceof Decimal64) {
247            final Decimal64 that = (Decimal64) obj;
248            return Double.doubleToLongBits(this.value) == Double
249                    .doubleToLongBits(that.value);
250        }
251        return false;
252    }
253
254    /**
255     * {@inheritDoc}
256     *
257     * The current implementation returns the same value as
258     * {@code new Double(this.doubleValue()).hashCode()}
259     *
260     * @see Double#hashCode()
261     */
262    @Override
263    public int hashCode() {
264        long v = Double.doubleToLongBits(value);
265        return (int) (v ^ (v >>> 32));
266    }
267
268    /**
269     * {@inheritDoc}
270     *
271     * The returned {@code String} is equal to
272     * {@code Double.toString(this.doubleValue())}
273     *
274     * @see Double#toString(double)
275     */
276    @Override
277    public String toString() {
278        return Double.toString(value);
279    }
280
281    /*
282     * Methods inspired by the Double class.
283     */
284
285    /**
286     * Returns {@code true} if {@code this} double precision number is infinite
287     * ({@link Double#POSITIVE_INFINITY} or {@link Double#NEGATIVE_INFINITY}).
288     *
289     * @return {@code true} if {@code this} number is infinite
290     */
291    public boolean isInfinite() {
292        return Double.isInfinite(value);
293    }
294
295    /**
296     * Returns {@code true} if {@code this} double precision number is
297     * Not-a-Number ({@code NaN}), false otherwise.
298     *
299     * @return {@code true} if {@code this} is {@code NaN}
300     */
301    public boolean isNaN() {
302        return Double.isNaN(value);
303    }
304
305    /** {@inheritDoc}
306     * @since 3.2
307     */
308    public double getReal() {
309        return value;
310    }
311
312    /** {@inheritDoc}
313     * @since 3.2
314     */
315    public Decimal64 add(final double a) {
316        return new Decimal64(value + a);
317    }
318
319    /** {@inheritDoc}
320     * @since 3.2
321     */
322    public Decimal64 subtract(final double a) {
323        return new Decimal64(value - a);
324    }
325
326    /** {@inheritDoc}
327     * @since 3.2
328     */
329    public Decimal64 multiply(final double a) {
330        return new Decimal64(value * a);
331    }
332
333    /** {@inheritDoc}
334     * @since 3.2
335     */
336    public Decimal64 divide(final double a) {
337        return new Decimal64(value / a);
338    }
339
340    /** {@inheritDoc}
341     * @since 3.2
342     */
343    public Decimal64 remainder(final double a) {
344        return new Decimal64(FastMath.IEEEremainder(value, a));
345    }
346
347    /** {@inheritDoc}
348     * @since 3.2
349     */
350    public Decimal64 remainder(final Decimal64 a) {
351        return new Decimal64(FastMath.IEEEremainder(value, a.value));
352    }
353
354    /** {@inheritDoc}
355     * @since 3.2
356     */
357    public Decimal64 abs() {
358        return new Decimal64(FastMath.abs(value));
359    }
360
361    /** {@inheritDoc}
362     * @since 3.2
363     */
364    public Decimal64 ceil() {
365        return new Decimal64(FastMath.ceil(value));
366    }
367
368    /** {@inheritDoc}
369     * @since 3.2
370     */
371    public Decimal64 floor() {
372        return new Decimal64(FastMath.floor(value));
373    }
374
375    /** {@inheritDoc}
376     * @since 3.2
377     */
378    public Decimal64 rint() {
379        return new Decimal64(FastMath.rint(value));
380    }
381
382    /** {@inheritDoc}
383     * @since 3.2
384     */
385    public long round() {
386        return FastMath.round(value);
387    }
388
389    /** {@inheritDoc}
390     * @since 3.2
391     */
392    public Decimal64 signum() {
393        return new Decimal64(FastMath.signum(value));
394    }
395
396    /** {@inheritDoc}
397     * @since 3.2
398     */
399    public Decimal64 copySign(final Decimal64 sign) {
400        return new Decimal64(FastMath.copySign(value, sign.value));
401    }
402
403    /** {@inheritDoc}
404     * @since 3.2
405     */
406    public Decimal64 copySign(final double sign) {
407        return new Decimal64(FastMath.copySign(value, sign));
408    }
409
410    /** {@inheritDoc}
411     * @since 3.2
412     */
413    public Decimal64 scalb(final int n) {
414        return new Decimal64(FastMath.scalb(value, n));
415    }
416
417    /** {@inheritDoc}
418     * @since 3.2
419     */
420    public Decimal64 hypot(final Decimal64 y) {
421        return new Decimal64(FastMath.hypot(value, y.value));
422    }
423
424    /** {@inheritDoc}
425     * @since 3.2
426     */
427    public Decimal64 sqrt() {
428        return new Decimal64(FastMath.sqrt(value));
429    }
430
431    /** {@inheritDoc}
432     * @since 3.2
433     */
434    public Decimal64 cbrt() {
435        return new Decimal64(FastMath.cbrt(value));
436    }
437
438    /** {@inheritDoc}
439     * @since 3.2
440     */
441    public Decimal64 rootN(final int n) {
442        if (value < 0) {
443            return new Decimal64(-FastMath.pow(-value, 1.0 / n));
444        } else {
445            return new Decimal64(FastMath.pow(value, 1.0 / n));
446        }
447    }
448
449    /** {@inheritDoc}
450     * @since 3.2
451     */
452    public Decimal64 pow(final double p) {
453        return new Decimal64(FastMath.pow(value, p));
454    }
455
456    /** {@inheritDoc}
457     * @since 3.2
458     */
459    public Decimal64 pow(final int n) {
460        return new Decimal64(FastMath.pow(value, n));
461    }
462
463    /** {@inheritDoc}
464     * @since 3.2
465     */
466    public Decimal64 pow(final Decimal64 e) {
467        return new Decimal64(FastMath.pow(value, e.value));
468    }
469
470    /** {@inheritDoc}
471     * @since 3.2
472     */
473    public Decimal64 exp() {
474        return new Decimal64(FastMath.exp(value));
475    }
476
477    /** {@inheritDoc}
478     * @since 3.2
479     */
480    public Decimal64 expm1() {
481        return new Decimal64(FastMath.expm1(value));
482    }
483
484    /** {@inheritDoc}
485     * @since 3.2
486     */
487    public Decimal64 log() {
488        return new Decimal64(FastMath.log(value));
489    }
490
491    /** {@inheritDoc}
492     * @since 3.2
493     */
494    public Decimal64 log1p() {
495        return new Decimal64(FastMath.log1p(value));
496    }
497
498    /** Base 10 logarithm.
499     * @return base 10 logarithm of the instance
500     * @since 3.2
501     */
502    public Decimal64 log10() {
503        return new Decimal64(FastMath.log10(value));
504    }
505
506    /** {@inheritDoc}
507     * @since 3.2
508     */
509    public Decimal64 cos() {
510        return new Decimal64(FastMath.cos(value));
511    }
512
513    /** {@inheritDoc}
514     * @since 3.2
515     */
516    public Decimal64 sin() {
517        return new Decimal64(FastMath.sin(value));
518    }
519
520    /** {@inheritDoc}
521     * @since 3.2
522     */
523    public Decimal64 tan() {
524        return new Decimal64(FastMath.tan(value));
525    }
526
527    /** {@inheritDoc}
528     * @since 3.2
529     */
530    public Decimal64 acos() {
531        return new Decimal64(FastMath.acos(value));
532    }
533
534    /** {@inheritDoc}
535     * @since 3.2
536     */
537    public Decimal64 asin() {
538        return new Decimal64(FastMath.asin(value));
539    }
540
541    /** {@inheritDoc}
542     * @since 3.2
543     */
544    public Decimal64 atan() {
545        return new Decimal64(FastMath.atan(value));
546    }
547
548    /** {@inheritDoc}
549     * @since 3.2
550     */
551    public Decimal64 atan2(final Decimal64 x) {
552        return new Decimal64(FastMath.atan2(value, x.value));
553    }
554
555    /** {@inheritDoc}
556     * @since 3.2
557     */
558    public Decimal64 cosh() {
559        return new Decimal64(FastMath.cosh(value));
560    }
561
562    /** {@inheritDoc}
563     * @since 3.2
564     */
565    public Decimal64 sinh() {
566        return new Decimal64(FastMath.sinh(value));
567    }
568
569    /** {@inheritDoc}
570     * @since 3.2
571     */
572    public Decimal64 tanh() {
573        return new Decimal64(FastMath.tanh(value));
574    }
575
576    /** {@inheritDoc}
577     * @since 3.2
578     */
579    public Decimal64 acosh() {
580        return new Decimal64(FastMath.acosh(value));
581    }
582
583    /** {@inheritDoc}
584     * @since 3.2
585     */
586    public Decimal64 asinh() {
587        return new Decimal64(FastMath.asinh(value));
588    }
589
590    /** {@inheritDoc}
591     * @since 3.2
592     */
593    public Decimal64 atanh() {
594        return new Decimal64(FastMath.atanh(value));
595    }
596
597    /** {@inheritDoc}
598     * @since 3.2
599     */
600    public Decimal64 linearCombination(final Decimal64[] a, final Decimal64[] b)
601        throws DimensionMismatchException {
602        if (a.length != b.length) {
603            throw new DimensionMismatchException(a.length, b.length);
604        }
605        final double[] aDouble = new double[a.length];
606        final double[] bDouble = new double[b.length];
607        for (int i = 0; i < a.length; ++i) {
608            aDouble[i] = a[i].value;
609            bDouble[i] = b[i].value;
610        }
611        return new Decimal64(MathArrays.linearCombination(aDouble, bDouble));
612    }
613
614    /** {@inheritDoc}
615     * @since 3.2
616     */
617    public Decimal64 linearCombination(final double[] a, final Decimal64[] b)
618        throws DimensionMismatchException {
619        if (a.length != b.length) {
620            throw new DimensionMismatchException(a.length, b.length);
621        }
622        final double[] bDouble = new double[b.length];
623        for (int i = 0; i < a.length; ++i) {
624            bDouble[i] = b[i].value;
625        }
626        return new Decimal64(MathArrays.linearCombination(a, bDouble));
627    }
628
629    /** {@inheritDoc}
630     * @since 3.2
631     */
632    public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
633                                       final Decimal64 a2, final Decimal64 b2) {
634        return new Decimal64(MathArrays.linearCombination(a1.value, b1.value,
635                                                          a2.value, b2.value));
636    }
637
638    /** {@inheritDoc}
639     * @since 3.2
640     */
641    public Decimal64 linearCombination(final double a1, final Decimal64 b1,
642                                       final double a2, final Decimal64 b2) {
643        return new Decimal64(MathArrays.linearCombination(a1, b1.value,
644                                                          a2, b2.value));
645    }
646
647    /** {@inheritDoc}
648     * @since 3.2
649     */
650    public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
651                                       final Decimal64 a2, final Decimal64 b2,
652                                       final Decimal64 a3, final Decimal64 b3) {
653        return new Decimal64(MathArrays.linearCombination(a1.value, b1.value,
654                                                          a2.value, b2.value,
655                                                          a3.value, b3.value));
656    }
657
658    /** {@inheritDoc}
659     * @since 3.2
660     */
661    public Decimal64 linearCombination(final double a1, final Decimal64 b1,
662                                       final double a2, final Decimal64 b2,
663                                       final double a3, final Decimal64 b3) {
664        return new Decimal64(MathArrays.linearCombination(a1, b1.value,
665                                                          a2, b2.value,
666                                                          a3, b3.value));
667    }
668
669    /** {@inheritDoc}
670     * @since 3.2
671     */
672    public Decimal64 linearCombination(final Decimal64 a1, final Decimal64 b1,
673                                       final Decimal64 a2, final Decimal64 b2,
674                                       final Decimal64 a3, final Decimal64 b3,
675                                       final Decimal64 a4, final Decimal64 b4) {
676        return new Decimal64(MathArrays.linearCombination(a1.value, b1.value,
677                                                          a2.value, b2.value,
678                                                          a3.value, b3.value,
679                                                          a4.value, b4.value));
680    }
681
682    /** {@inheritDoc}
683     * @since 3.2
684     */
685    public Decimal64 linearCombination(final double a1, final Decimal64 b1,
686                                       final double a2, final Decimal64 b2,
687                                       final double a3, final Decimal64 b3,
688                                       final double a4, final Decimal64 b4) {
689        return new Decimal64(MathArrays.linearCombination(a1, b1.value,
690                                                          a2, b2.value,
691                                                          a3, b3.value,
692                                                          a4, b4.value));
693    }
694
695}