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