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 */ 017package org.apache.commons.math3.util; 018 019 020import java.io.Serializable; 021import java.math.BigDecimal; 022import java.math.BigInteger; 023import java.math.MathContext; 024import java.math.RoundingMode; 025 026import org.apache.commons.math3.Field; 027import org.apache.commons.math3.FieldElement; 028import org.apache.commons.math3.exception.MathArithmeticException; 029import 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 */ 039public class BigReal implements FieldElement<BigReal>, Comparable<BigReal>, Serializable { 040 041 /** A big real representing 0. */ 042 public static final BigReal ZERO = new BigReal(BigDecimal.ZERO); 043 044 /** A big real representing 1. */ 045 public static final BigReal ONE = new BigReal(BigDecimal.ONE); 046 047 /** Serializable version identifier. */ 048 private static final long serialVersionUID = 4984534880991310382L; 049 050 /** Underlying BigDecimal. */ 051 private final BigDecimal d; 052 053 /** Rounding mode for divisions. **/ 054 private RoundingMode roundingMode = RoundingMode.HALF_UP; 055 056 /*** BigDecimal scale ***/ 057 private int scale = 64; 058 059 /** Build an instance from a BigDecimal. 060 * @param val value of the instance 061 */ 062 public BigReal(BigDecimal val) { 063 d = val; 064 } 065 066 /** Build an instance from a BigInteger. 067 * @param val value of the instance 068 */ 069 public BigReal(BigInteger val) { 070 d = new BigDecimal(val); 071 } 072 073 /** Build an instance from an unscaled BigInteger. 074 * @param unscaledVal unscaled value 075 * @param scale scale to use 076 */ 077 public BigReal(BigInteger unscaledVal, int scale) { 078 d = new BigDecimal(unscaledVal, scale); 079 } 080 081 /** Build an instance from an unscaled BigInteger. 082 * @param unscaledVal unscaled value 083 * @param scale scale to use 084 * @param mc to used 085 */ 086 public BigReal(BigInteger unscaledVal, int scale, MathContext mc) { 087 d = new BigDecimal(unscaledVal, scale, mc); 088 } 089 090 /** Build an instance from a BigInteger. 091 * @param val value of the instance 092 * @param mc context to use 093 */ 094 public BigReal(BigInteger val, MathContext mc) { 095 d = new BigDecimal(val, mc); 096 } 097 098 /** Build an instance from a characters representation. 099 * @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 public BigReal add(BigReal a) { 232 return new BigReal(d.add(a.d)); 233 } 234 235 /** {@inheritDoc} */ 236 public BigReal subtract(BigReal a) { 237 return new BigReal(d.subtract(a.d)); 238 } 239 240 /** {@inheritDoc} */ 241 public BigReal negate() { 242 return new BigReal(d.negate()); 243 } 244 245 /** 246 * {@inheritDoc} 247 * 248 * @throws MathArithmeticException if {@code a} is zero 249 */ 250 public BigReal divide(BigReal a) throws MathArithmeticException { 251 try { 252 return new BigReal(d.divide(a.d, scale, roundingMode)); 253 } catch (ArithmeticException e) { 254 // Division by zero has occurred 255 throw new MathArithmeticException(LocalizedFormats.ZERO_NOT_ALLOWED); 256 } 257 } 258 259 /** 260 * {@inheritDoc} 261 * 262 * @throws MathArithmeticException if {@code this} is zero 263 */ 264 public BigReal reciprocal() throws MathArithmeticException { 265 try { 266 return new BigReal(BigDecimal.ONE.divide(d, scale, roundingMode)); 267 } catch (ArithmeticException e) { 268 // Division by zero has occurred 269 throw new MathArithmeticException(LocalizedFormats.ZERO_NOT_ALLOWED); 270 } 271 } 272 273 /** {@inheritDoc} */ 274 public BigReal multiply(BigReal a) { 275 return new BigReal(d.multiply(a.d)); 276 } 277 278 /** {@inheritDoc} */ 279 public BigReal multiply(final int n) { 280 return new BigReal(d.multiply(new BigDecimal(n))); 281 } 282 283 /** {@inheritDoc} */ 284 public int compareTo(BigReal a) { 285 return d.compareTo(a.d); 286 } 287 288 /** Get the double value corresponding to the instance. 289 * @return double value corresponding to the instance 290 */ 291 public double doubleValue() { 292 return d.doubleValue(); 293 } 294 295 /** Get the BigDecimal value corresponding to the instance. 296 * @return BigDecimal value corresponding to the instance 297 */ 298 public BigDecimal bigDecimalValue() { 299 return d; 300 } 301 302 /** {@inheritDoc} */ 303 @Override 304 public boolean equals(Object other) { 305 if (this == other){ 306 return true; 307 } 308 309 if (other instanceof BigReal){ 310 return d.equals(((BigReal) other).d); 311 } 312 return false; 313 } 314 315 /** {@inheritDoc} */ 316 @Override 317 public int hashCode() { 318 return d.hashCode(); 319 } 320 321 /** {@inheritDoc} */ 322 public Field<BigReal> getField() { 323 return BigRealField.getInstance(); 324 } 325}