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 * http://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 package org.apache.commons.math4.legacy.linear;
18
19
20 import java.io.Serializable;
21 import java.math.BigDecimal;
22 import java.math.BigInteger;
23 import java.math.MathContext;
24 import java.math.RoundingMode;
25
26 import org.apache.commons.math4.legacy.core.Field;
27 import org.apache.commons.math4.legacy.core.FieldElement;
28 import org.apache.commons.math4.legacy.exception.MathArithmeticException;
29 import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
30
31 /**
32 * Arbitrary precision decimal number.
33 * <p>
34 * This class is a simple wrapper around the standard <code>BigDecimal</code>
35 * in order to implement the {@link FieldElement} interface.
36 * </p>
37 * @since 2.0
38 */
39 public class BigReal implements FieldElement<BigReal>, Comparable<BigReal>, Serializable {
40
41 /** A big real representing 0. */
42 public static final BigReal ZERO = new BigReal(BigDecimal.ZERO);
43
44 /** A big real representing 1. */
45 public static final BigReal ONE = new BigReal(BigDecimal.ONE);
46
47 /** Serializable version identifier. */
48 private static final long serialVersionUID = 4984534880991310382L;
49
50 /** Underlying BigDecimal. */
51 private final BigDecimal d;
52
53 /** Rounding mode for divisions. */
54 private RoundingMode roundingMode = RoundingMode.HALF_UP;
55
56 /** BigDecimal scale. */
57 private int scale = 64;
58
59 /** Build an instance from a BigDecimal.
60 * @param val value of the instance
61 */
62 public BigReal(BigDecimal val) {
63 d = val;
64 }
65
66 /** Build an instance from a BigInteger.
67 * @param val value of the instance
68 */
69 public BigReal(BigInteger val) {
70 d = new BigDecimal(val);
71 }
72
73 /** Build an instance from an unscaled BigInteger.
74 * @param unscaledVal unscaled value
75 * @param scale scale to use
76 */
77 public BigReal(BigInteger unscaledVal, int scale) {
78 d = new BigDecimal(unscaledVal, scale);
79 }
80
81 /** Build an instance from an unscaled BigInteger.
82 * @param unscaledVal unscaled value
83 * @param scale scale to use
84 * @param mc to used
85 */
86 public BigReal(BigInteger unscaledVal, int scale, MathContext mc) {
87 d = new BigDecimal(unscaledVal, scale, mc);
88 }
89
90 /** Build an instance from a BigInteger.
91 * @param val value of the instance
92 * @param mc context to use
93 */
94 public BigReal(BigInteger val, MathContext mc) {
95 d = new BigDecimal(val, mc);
96 }
97
98 /** Build an instance from a characters representation.
99 * @param in character representation of the value
100 */
101 public BigReal(char[] in) {
102 d = new BigDecimal(in);
103 }
104
105 /** Build an instance from a characters representation.
106 * @param in character representation of the value
107 * @param offset offset of the first character to analyze
108 * @param len length of the array slice to analyze
109 */
110 public BigReal(char[] in, int offset, int len) {
111 d = new BigDecimal(in, offset, len);
112 }
113
114 /** Build an instance from a characters representation.
115 * @param in character representation of the value
116 * @param offset offset of the first character to analyze
117 * @param len length of the array slice to analyze
118 * @param mc context to use
119 */
120 public BigReal(char[] in, int offset, int len, MathContext mc) {
121 d = new BigDecimal(in, offset, len, mc);
122 }
123
124 /** Build an instance from a characters representation.
125 * @param in character representation of the value
126 * @param mc context to use
127 */
128 public BigReal(char[] in, MathContext mc) {
129 d = new BigDecimal(in, mc);
130 }
131
132 /** Build an instance from a double.
133 * @param val value of the instance
134 */
135 public BigReal(double val) {
136 d = new BigDecimal(val);
137 }
138
139 /** Build an instance from a double.
140 * @param val value of the instance
141 * @param mc context to use
142 */
143 public BigReal(double val, MathContext mc) {
144 d = new BigDecimal(val, mc);
145 }
146
147 /** Build an instance from an int.
148 * @param val value of the instance
149 */
150 public BigReal(int val) {
151 d = new BigDecimal(val);
152 }
153
154 /** Build an instance from an int.
155 * @param val value of the instance
156 * @param mc context to use
157 */
158 public BigReal(int val, MathContext mc) {
159 d = new BigDecimal(val, mc);
160 }
161
162 /** Build an instance from a long.
163 * @param val value of the instance
164 */
165 public BigReal(long val) {
166 d = new BigDecimal(val);
167 }
168
169 /** Build an instance from a long.
170 * @param val value of the instance
171 * @param mc context to use
172 */
173 public BigReal(long val, MathContext mc) {
174 d = new BigDecimal(val, mc);
175 }
176
177 /** Build an instance from a String representation.
178 * @param val character representation of the value
179 */
180 public BigReal(String val) {
181 d = new BigDecimal(val);
182 }
183
184 /** Build an instance from a String representation.
185 * @param val character representation of the value
186 * @param mc context to use
187 */
188 public BigReal(String val, MathContext mc) {
189 d = new BigDecimal(val, mc);
190 }
191
192 /***
193 * Gets the rounding mode for division operations.
194 * The default is {@code RoundingMode.HALF_UP}
195 * @return the rounding mode.
196 * @since 2.1
197 */
198 public RoundingMode getRoundingMode() {
199 return roundingMode;
200 }
201
202 /***
203 * Sets the rounding mode for decimal divisions.
204 * @param roundingMode rounding mode for decimal divisions
205 * @since 2.1
206 */
207 public void setRoundingMode(RoundingMode roundingMode) {
208 this.roundingMode = roundingMode;
209 }
210
211 /***
212 * Sets the scale for division operations.
213 * The default is 64
214 * @return the scale
215 * @since 2.1
216 */
217 public int getScale() {
218 return scale;
219 }
220
221 /***
222 * Sets the scale for division operations.
223 * @param scale scale for division operations
224 * @since 2.1
225 */
226 public void setScale(int scale) {
227 this.scale = scale;
228 }
229
230 /** {@inheritDoc} */
231 @Override
232 public BigReal add(BigReal a) {
233 return new BigReal(d.add(a.d));
234 }
235
236 /** {@inheritDoc} */
237 @Override
238 public BigReal subtract(BigReal a) {
239 return new BigReal(d.subtract(a.d));
240 }
241
242 /** {@inheritDoc} */
243 @Override
244 public BigReal negate() {
245 return new BigReal(d.negate());
246 }
247
248 /**
249 * {@inheritDoc}
250 *
251 * @throws MathArithmeticException if {@code a} is zero
252 */
253 @Override
254 public BigReal divide(BigReal a) throws MathArithmeticException {
255 try {
256 return new BigReal(d.divide(a.d, scale, roundingMode));
257 } catch (ArithmeticException e) {
258 // Division by zero has occurred
259 throw new MathArithmeticException(LocalizedFormats.ZERO_NOT_ALLOWED);
260 }
261 }
262
263 /**
264 * {@inheritDoc}
265 *
266 * @throws MathArithmeticException if {@code this} is zero
267 */
268 @Override
269 public BigReal reciprocal() throws MathArithmeticException {
270 try {
271 return new BigReal(BigDecimal.ONE.divide(d, scale, roundingMode));
272 } catch (ArithmeticException e) {
273 // Division by zero has occurred
274 throw new MathArithmeticException(LocalizedFormats.ZERO_NOT_ALLOWED);
275 }
276 }
277
278 /** {@inheritDoc} */
279 @Override
280 public BigReal multiply(BigReal a) {
281 return new BigReal(d.multiply(a.d));
282 }
283
284 /** {@inheritDoc} */
285 @Override
286 public BigReal multiply(final int n) {
287 return new BigReal(d.multiply(new BigDecimal(n)));
288 }
289
290 /** {@inheritDoc} */
291 @Override
292 public int compareTo(BigReal a) {
293 return d.compareTo(a.d);
294 }
295
296 /** Get the double value corresponding to the instance.
297 * @return double value corresponding to the instance
298 */
299 public double doubleValue() {
300 return d.doubleValue();
301 }
302
303 /** Get the BigDecimal value corresponding to the instance.
304 * @return BigDecimal value corresponding to the instance
305 */
306 public BigDecimal bigDecimalValue() {
307 return d;
308 }
309
310 /** {@inheritDoc} */
311 @Override
312 public boolean equals(Object other) {
313 if (this == other){
314 return true;
315 }
316
317 if (other instanceof BigReal) {
318 return d.compareTo(((BigReal) other).d) == 0;
319 }
320 return false;
321 }
322
323 /** {@inheritDoc} */
324 @Override
325 public int hashCode() {
326 return Double.hashCode(d.doubleValue());
327 }
328
329 /** {@inheritDoc} */
330 @Override
331 public Field<BigReal> getField() {
332 return BigRealField.getInstance();
333 }
334 }