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 }