    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     */
    017    package org.apache.commons.math3.util;
    018
    019
    020    import java.io.Serializable;
    021    import java.math.BigDecimal;
    022    import java.math.BigInteger;
    023    import java.math.MathContext;
    024    import java.math.RoundingMode;
    025
    026    import org.apache.commons.math3.Field;
    027    import org.apache.commons.math3.FieldElement;
    028    import org.apache.commons.math3.exception.MathArithmeticException;
    029    import org.apache.commons.math3.exception.util.LocalizedFormats;
    030
    031    /**
    032     * Arbitrary precision decimal number.
    033     * <p>
    034     * This class is a simple wrapper around the standard <code>BigDecimal</code>
    035     * in order to implement the {@link FieldElement} interface.
    036     * </p>
    037     * @since 2.0
    038     * @version $Id: BigReal.java 1416643 2012-12-03 19:37:14Z tn $
    039     */
    040    public class BigReal implements FieldElement<BigReal>, Comparable<BigReal>, Serializable {
    041
    042        /** A big real representing 0. */
    043        public static final BigReal ZERO = new BigReal(BigDecimal.ZERO);
    044
    045        /** A big real representing 1. */
    046        public static final BigReal ONE = new BigReal(BigDecimal.ONE);
    047
    048        /** Serializable version identifier. */
    049        private static final long serialVersionUID = 4984534880991310382L;
    050
    051        /** Underlying BigDecimal. */
    052        private final BigDecimal d;
    053
    054        /** Rounding mode for divisions. **/
    055        private RoundingMode roundingMode = RoundingMode.HALF_UP;
    056
    057        /*** BigDecimal scale ***/
    058        private int scale = 64;
    059
    060        /** Build an instance from a BigDecimal.
    061         * @param val value of the instance
    062         */
    063        public BigReal(BigDecimal val) {
    064            d =  val;
    065        }
    066
    067        /** Build an instance from a BigInteger.
    068         * @param val value of the instance
    069         */
    070        public BigReal(BigInteger val) {
    071            d = new BigDecimal(val);
    072        }
    073
    074        /** Build an instance from an unscaled BigInteger.
    075         * @param unscaledVal unscaled value
    076         * @param scale scale to use
    077         */
    078        public BigReal(BigInteger unscaledVal, int scale) {
    079            d = new BigDecimal(unscaledVal, scale);
    080        }
    081
    082        /** Build an instance from an unscaled BigInteger.
    083         * @param unscaledVal unscaled value
    084         * @param scale scale to use
    085         * @param mc to used
    086         */
    087        public BigReal(BigInteger unscaledVal, int scale, MathContext mc) {
    088            d = new BigDecimal(unscaledVal, scale, mc);
    089        }
    090
    091        /** Build an instance from a BigInteger.
    092         * @param val value of the instance
    093         * @param mc context to use
    094         */
    095        public BigReal(BigInteger val, MathContext mc) {
    096            d = new BigDecimal(val, mc);
    097        }
    098
    099        /** Build an instance from a characters representation.
    100         * @param in character representation of the value
    101         */
    102        public BigReal(char[] in) {
    103            d = new BigDecimal(in);
    104        }
    105
    106        /** Build an instance from a characters representation.
    107         * @param in character representation of the value
    108         * @param offset offset of the first character to analyze
    109         * @param len length of the array slice to analyze
    110         */
    111        public BigReal(char[] in, int offset, int len) {
    112            d = new BigDecimal(in, offset, len);
    113        }
    114
    115        /** Build an instance from a characters representation.
    116         * @param in character representation of the value
    117         * @param offset offset of the first character to analyze
    118         * @param len length of the array slice to analyze
    119         * @param mc context to use
    120         */
    121        public BigReal(char[] in, int offset, int len, MathContext mc) {
    122            d = new BigDecimal(in, offset, len, mc);
    123        }
    124
    125        /** Build an instance from a characters representation.
    126         * @param in character representation of the value
    127         * @param mc context to use
    128         */
    129        public BigReal(char[] in, MathContext mc) {
    130            d = new BigDecimal(in, mc);
    131        }
    132
    133        /** Build an instance from a double.
    134         * @param val value of the instance
    135         */
    136        public BigReal(double val) {
    137            d = new BigDecimal(val);
    138        }
    139
    140        /** Build an instance from a double.
    141         * @param val value of the instance
    142         * @param mc context to use
    143         */
    144        public BigReal(double val, MathContext mc) {
    145            d = new BigDecimal(val, mc);
    146        }
    147
    148        /** Build an instance from an int.
    149         * @param val value of the instance
    150         */
    151        public BigReal(int val) {
    152            d = new BigDecimal(val);
    153        }
    154
    155        /** Build an instance from an int.
    156         * @param val value of the instance
    157         * @param mc context to use
    158         */
    159        public BigReal(int val, MathContext mc) {
    160            d = new BigDecimal(val, mc);
    161        }
    162
    163        /** Build an instance from a long.
    164         * @param val value of the instance
    165         */
    166        public BigReal(long val) {
    167            d = new BigDecimal(val);
    168        }
    169
    170        /** Build an instance from a long.
    171         * @param val value of the instance
    172         * @param mc context to use
    173         */
    174        public BigReal(long val, MathContext mc) {
    175            d = new BigDecimal(val, mc);
    176        }
    177
    178        /** Build an instance from a String representation.
    179         * @param val character representation of the value
    180         */
    181        public BigReal(String val) {
    182            d = new BigDecimal(val);
    183        }
    184
    185        /** Build an instance from a String representation.
    186         * @param val character representation of the value
    187         * @param mc context to use
    188         */
    189        public BigReal(String val, MathContext mc)  {
    190            d = new BigDecimal(val, mc);
    191        }
    192
    193        /***
    194         * Gets the rounding mode for division operations
    195         * The default is {@code RoundingMode.HALF_UP}
    196         * @return the rounding mode.
    197         * @since 2.1
    198         */
    199        public RoundingMode getRoundingMode() {
    200            return roundingMode;
    201        }
    202
    203        /***
    204         * Sets the rounding mode for decimal divisions.
    205         * @param roundingMode rounding mode for decimal divisions
    206         * @since 2.1
    207         */
    208        public void setRoundingMode(RoundingMode roundingMode) {
    209            this.roundingMode = roundingMode;
    210        }
    211
    212        /***
    213         * Sets the scale for division operations.
    214         * The default is 64
    215         * @return the scale
    216         * @since 2.1
    217         */
    218        public int getScale() {
    219            return scale;
    220        }
    221
    222        /***
    223         * Sets the scale for division operations.
    224         * @param scale scale for division operations
    225         * @since 2.1
    226         */
    227        public void setScale(int scale) {
    228            this.scale = scale;
    229        }
    230
    231        /** {@inheritDoc} */
    232        public BigReal add(BigReal a) {
    233            return new BigReal(d.add(a.d));
    234        }
    235
    236        /** {@inheritDoc} */
    237        public BigReal subtract(BigReal a) {
    238            return new BigReal(d.subtract(a.d));
    239        }
    240
    241        /** {@inheritDoc} */
    242        public BigReal negate() {
    243            return new BigReal(d.negate());
    244        }
    245
    246        /**
    247         * {@inheritDoc}
    248         *
    249         * @throws MathArithmeticException if {@code a} is zero
    250         */
    251        public BigReal divide(BigReal a) throws MathArithmeticException {
    252            try {
    253                return new BigReal(d.divide(a.d, scale, roundingMode));
    254            } catch (ArithmeticException e) {
    255                // Division by zero has occured
    256                throw new MathArithmeticException(LocalizedFormats.ZERO_NOT_ALLOWED);
    257            }
    258        }
    259
    260        /**
    261         * {@inheritDoc}
    262         *
    263         * @throws MathArithmeticException if {@code this} is zero
    264         */
    265        public BigReal reciprocal() throws MathArithmeticException {
    266            try {
    267                return new BigReal(BigDecimal.ONE.divide(d, scale, roundingMode));
    268            } catch (ArithmeticException e) {
    269                // Division by zero has occured
    270                throw new MathArithmeticException(LocalizedFormats.ZERO_NOT_ALLOWED);
    271            }
    272        }
    273
    274        /** {@inheritDoc} */
    275        public BigReal multiply(BigReal a) {
    276            return new BigReal(d.multiply(a.d));
    277        }
    278
    279        /** {@inheritDoc} */
    280        public BigReal multiply(final int n) {
    281            return new BigReal(d.multiply(new BigDecimal(n)));
    282        }
    283
    284        /** {@inheritDoc} */
    285        public int compareTo(BigReal a) {
    286            return d.compareTo(a.d);
    287        }
    288
    289        /** Get the double value corresponding to the instance.
    290         * @return double value corresponding to the instance
    291         */
    292        public double doubleValue() {
    293            return d.doubleValue();
    294        }
    295
    296        /** Get the BigDecimal value corresponding to the instance.
    297         * @return BigDecimal value corresponding to the instance
    298         */
    299        public BigDecimal bigDecimalValue() {
    300            return d;
    301        }
    302
    303        /** {@inheritDoc} */
    304        @Override
    305        public boolean equals(Object other) {
    306            if (this == other){
    307                return true;
    308            }
    309
    310            if (other instanceof BigReal){
    311                return d.equals(((BigReal) other).d);
    312            }
    313            return false;
    314        }
    315
    316        /** {@inheritDoc} */
    317        @Override
    318        public int hashCode() {
    319            return d.hashCode();
    320        }
    321
    322        /** {@inheritDoc} */
    323        public Field<BigReal> getField() {
    324            return BigRealField.getInstance();
    325        }
    326    }