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    }