001/* 002 * The MIT License (MIT) 003 * 004 * Copyright (c) 2015-2024 decimal4j (tools4j), Marco Terzer 005 * 006 * Permission is hereby granted, free of charge, to any person obtaining a copy 007 * of this software and associated documentation files (the "Software"), to deal 008 * in the Software without restriction, including without limitation the rights 009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010 * copies of the Software, and to permit persons to whom the Software is 011 * furnished to do so, subject to the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be included in all 014 * copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 022 * SOFTWARE. 023 */ 024package org.decimal4j.mutable; 025 026import java.math.BigDecimal; 027import java.math.BigInteger; 028import java.math.RoundingMode; 029 030import org.decimal4j.api.Decimal; 031import org.decimal4j.api.DecimalArithmetic; 032import org.decimal4j.base.AbstractMutableDecimal; 033import org.decimal4j.exact.Multipliable17f; 034import org.decimal4j.factory.Factory17f; 035import org.decimal4j.immutable.Decimal17f; 036import org.decimal4j.scale.Scale17f; 037 038/** 039 * <code>MutableDecimal17f</code> represents a mutable decimal number with a fixed 040 * number of 17 digits to the right of the decimal point. 041 * <p> 042 * All methods for this class throw {@code NullPointerException} when passed a 043 * {@code null} object reference for any input parameter. 044 */ 045public final class MutableDecimal17f extends AbstractMutableDecimal<Scale17f, MutableDecimal17f> implements Cloneable { 046 047 private static final long serialVersionUID = 1L; 048 049 /** 050 * Constructs a new {@code MutableDecimal17f} with value zero. 051 * @see #zero() 052 */ 053 public MutableDecimal17f() { 054 super(0); 055 } 056 057 /** 058 * Private constructor with unscaled value. 059 * 060 * @param unscaledValue the unscaled value 061 * @param scale the scale metrics used to distinguish this constructor signature 062 * from {@link #MutableDecimal17f(long)} 063 */ 064 private MutableDecimal17f(long unscaledValue, Scale17f scale) { 065 super(unscaledValue); 066 } 067 068 /** 069 * Translates the string representation of a {@code Decimal} into a 070 * {@code MutableDecimal17f}. The string representation consists 071 * of an optional sign, {@code '+'} or {@code '-'} , followed by a sequence 072 * of zero or more decimal digits ("the integer"), optionally followed by a 073 * fraction. 074 * <p> 075 * The fraction consists of a decimal point followed by zero or more decimal 076 * digits. The string must contain at least one digit in either the integer 077 * or the fraction. If the fraction contains more than 17 digits, the 078 * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An 079 * exception is thrown if the value is too large to be represented as a 080 * {@code MutableDecimal17f}. 081 * 082 * @param value 083 * String value to convert into a {@code MutableDecimal17f} 084 * @throws NumberFormatException 085 * if {@code value} does not represent a valid {@code Decimal} 086 * or if the value is too large to be represented as a 087 * {@code MutableDecimal17f} 088 * @see #set(String, RoundingMode) 089 */ 090 public MutableDecimal17f(String value) { 091 this(); 092 set(value); 093 } 094 095 /** 096 * Constructs a {@code MutableDecimal17f} whose value is numerically equal 097 * to that of the specified {@code long} value. An exception is thrown if the 098 * specified value is too large to be represented as a {@code MutableDecimal17f}. 099 * 100 * @param value 101 * long value to convert into a {@code MutableDecimal17f} 102 * @throws IllegalArgumentException 103 * if {@code value} is too large to be represented as a 104 * {@code MutableDecimal17f} 105 */ 106 public MutableDecimal17f(long value) { 107 this(); 108 set(value); 109 } 110 111 /** 112 * Constructs a {@code MutableDecimal17f} whose value is calculated by 113 * rounding the specified {@code double} argument to scale 17 using 114 * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the 115 * specified value is too large to be represented as a {@code MutableDecimal17f}. 116 * 117 * @param value 118 * double value to convert into a {@code MutableDecimal17f} 119 * @throws IllegalArgumentException 120 * if {@code value} is NaN or infinite or if the magnitude is too large 121 * for the double to be represented as a {@code MutableDecimal17f} 122 * @see #set(double, RoundingMode) 123 * @see #set(float) 124 * @see #set(float, RoundingMode) 125 */ 126 public MutableDecimal17f(double value) { 127 this(); 128 set(value); 129 } 130 131 /** 132 * Constructs a {@code MutableDecimal17f} whose value is numerically equal to 133 * that of the specified {@link BigInteger} value. An exception is thrown if the 134 * specified value is too large to be represented as a {@code MutableDecimal17f}. 135 * 136 * @param value 137 * {@code BigInteger} value to convert into a {@code MutableDecimal17f} 138 * @throws IllegalArgumentException 139 * if {@code value} is too large to be represented as a {@code MutableDecimal17f} 140 */ 141 public MutableDecimal17f(BigInteger value) { 142 this(); 143 set(value); 144 } 145 146 /** 147 * Constructs a {@code MutableDecimal17f} whose value is calculated by 148 * rounding the specified {@link BigDecimal} argument to scale 17 using 149 * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the 150 * specified value is too large to be represented as a {@code MutableDecimal17f}. 151 * 152 * @param value 153 * {@code BigDecimal} value to convert into a {@code MutableDecimal17f} 154 * @throws IllegalArgumentException 155 * if {@code value} is too large to be represented as a {@code MutableDecimal17f} 156 * @see #set(BigDecimal, RoundingMode) 157 */ 158 public MutableDecimal17f(BigDecimal value) { 159 this(); 160 set(value); 161 } 162 163 /** 164 * Constructs a {@code MutableDecimal17f} whose value is numerically equal to 165 * that of the specified {@link Decimal17f} value. 166 * 167 * @param value 168 * {@code Decimal17f} value to convert into a {@code MutableDecimal17f} 169 */ 170 public MutableDecimal17f(Decimal17f value) { 171 this(value.unscaledValue(), Decimal17f.METRICS); 172 } 173 174 /** 175 * Constructs a {@code MutableDecimal17f} whose value is calculated by 176 * rounding the specified {@link Decimal} argument to scale 17 using 177 * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if 178 * the specified value is too large to be represented as a {@code MutableDecimal17f}. 179 * 180 * @param value 181 * Decimal value to convert into a {@code MutableDecimal17f} 182 * @throws IllegalArgumentException 183 * if {@code value} is too large to be represented as a {@code MutableDecimal17f} 184 * @see #set(Decimal, RoundingMode) 185 */ 186 public MutableDecimal17f(Decimal<?> value) { 187 this(); 188 setUnscaled(value.unscaledValue(), value.getScale()); 189 } 190 191 @Override 192 protected final MutableDecimal17f create(long unscaled) { 193 return new MutableDecimal17f(unscaled, Decimal17f.METRICS); 194 } 195 196 @Override 197 protected final MutableDecimal17f[] createArray(int length) { 198 return new MutableDecimal17f[length]; 199 } 200 201 @Override 202 protected final MutableDecimal17f self() { 203 return this; 204 } 205 206 @Override 207 public final Scale17f getScaleMetrics() { 208 return Decimal17f.METRICS; 209 } 210 211 @Override 212 public final int getScale() { 213 return Decimal17f.SCALE; 214 } 215 216 @Override 217 public Factory17f getFactory() { 218 return Decimal17f.FACTORY; 219 } 220 221 @Override 222 protected DecimalArithmetic getDefaultArithmetic() { 223 return Decimal17f.DEFAULT_ARITHMETIC; 224 } 225 226 @Override 227 protected DecimalArithmetic getDefaultCheckedArithmetic() { 228 return Decimal17f.METRICS.getDefaultCheckedArithmetic(); 229 } 230 231 @Override 232 protected DecimalArithmetic getRoundingDownArithmetic() { 233 return Decimal17f.METRICS.getRoundingDownArithmetic(); 234 } 235 236 @Override 237 protected DecimalArithmetic getRoundingFloorArithmetic() { 238 return Decimal17f.METRICS.getRoundingFloorArithmetic(); 239 } 240 241 @Override 242 protected DecimalArithmetic getRoundingHalfEvenArithmetic() { 243 return Decimal17f.METRICS.getRoundingHalfEvenArithmetic(); 244 } 245 246 @Override 247 protected DecimalArithmetic getRoundingUnnecessaryArithmetic() { 248 return Decimal17f.METRICS.getRoundingUnnecessaryArithmetic(); 249 } 250 251 @Override 252 public MutableDecimal17f clone() { 253 return new MutableDecimal17f(unscaledValue(), Decimal17f.METRICS); 254 } 255 256 /** 257 * Returns a new {@code MutableDecimal17f} whose value is equal to 258 * <code>unscaledValue * 10<sup>-17</sup></code>. 259 * 260 * @param unscaledValue 261 * the unscaled decimal value to convert 262 * @return a new {@code MutableDecimal17f} value initialised with <code>unscaledValue * 10<sup>-17</sup></code> 263 * @see #setUnscaled(long, int) 264 * @see #setUnscaled(long, int, RoundingMode) 265 */ 266 public static MutableDecimal17f unscaled(long unscaledValue) { 267 return new MutableDecimal17f(unscaledValue, Decimal17f.METRICS); 268 } 269 270 /** 271 * Returns a new {@code MutableDecimal17f} whose value is equal to zero. 272 * 273 * @return a new {@code MutableDecimal17f} value initialised with 0. 274 */ 275 public static MutableDecimal17f zero() { 276 return new MutableDecimal17f(); 277 } 278 279 /** 280 * Returns a new {@code MutableDecimal17f} whose value is equal to one ULP. 281 * 282 * @return a new {@code MutableDecimal17f} value initialised with 10<sup>-17</sup>. 283 */ 284 public static MutableDecimal17f ulp() { 285 return new MutableDecimal17f(Decimal17f.ULP); 286 } 287 288 /** 289 * Returns a new {@code MutableDecimal17f} whose value is equal to one. 290 * 291 * @return a new {@code MutableDecimal17f} value initialised with 1. 292 */ 293 public static MutableDecimal17f one() { 294 return new MutableDecimal17f(Decimal17f.ONE); 295 } 296 297 /** 298 * Returns a new {@code MutableDecimal17f} whose value is equal to two. 299 * 300 * @return a new {@code MutableDecimal17f} value initialised with 2. 301 */ 302 public static MutableDecimal17f two() { 303 return new MutableDecimal17f(Decimal17f.TWO); 304 } 305 306 /** 307 * Returns a new {@code MutableDecimal17f} whose value is equal to three. 308 * 309 * @return a new {@code MutableDecimal17f} value initialised with 3. 310 */ 311 public static MutableDecimal17f three() { 312 return new MutableDecimal17f(Decimal17f.THREE); 313 } 314 315 /** 316 * Returns a new {@code MutableDecimal17f} whose value is equal to four. 317 * 318 * @return a new {@code MutableDecimal17f} value initialised with 4. 319 */ 320 public static MutableDecimal17f four() { 321 return new MutableDecimal17f(Decimal17f.FOUR); 322 } 323 324 /** 325 * Returns a new {@code MutableDecimal17f} whose value is equal to five. 326 * 327 * @return a new {@code MutableDecimal17f} value initialised with 5. 328 */ 329 public static MutableDecimal17f five() { 330 return new MutableDecimal17f(Decimal17f.FIVE); 331 } 332 333 /** 334 * Returns a new {@code MutableDecimal17f} whose value is equal to six. 335 * 336 * @return a new {@code MutableDecimal17f} value initialised with 6. 337 */ 338 public static MutableDecimal17f six() { 339 return new MutableDecimal17f(Decimal17f.SIX); 340 } 341 342 /** 343 * Returns a new {@code MutableDecimal17f} whose value is equal to seven. 344 * 345 * @return a new {@code MutableDecimal17f} value initialised with 7. 346 */ 347 public static MutableDecimal17f seven() { 348 return new MutableDecimal17f(Decimal17f.SEVEN); 349 } 350 351 /** 352 * Returns a new {@code MutableDecimal17f} whose value is equal to eight. 353 * 354 * @return a new {@code MutableDecimal17f} value initialised with 8. 355 */ 356 public static MutableDecimal17f eight() { 357 return new MutableDecimal17f(Decimal17f.EIGHT); 358 } 359 360 /** 361 * Returns a new {@code MutableDecimal17f} whose value is equal to nine. 362 * 363 * @return a new {@code MutableDecimal17f} value initialised with 9. 364 */ 365 public static MutableDecimal17f nine() { 366 return new MutableDecimal17f(Decimal17f.NINE); 367 } 368 369 /** 370 * Returns a new {@code MutableDecimal17f} whose value is equal to ten. 371 * 372 * @return a new {@code MutableDecimal17f} value initialised with 10. 373 */ 374 public static MutableDecimal17f ten() { 375 return new MutableDecimal17f(Decimal17f.TEN); 376 } 377 378 /** 379 * Returns a new {@code MutableDecimal17f} whose value is equal to minus one. 380 * 381 * @return a new {@code MutableDecimal17f} value initialised with -1. 382 */ 383 public static MutableDecimal17f minusOne() { 384 return new MutableDecimal17f(Decimal17f.MINUS_ONE); 385 } 386 387 /** 388 * Returns a new {@code MutableDecimal17f} whose value is equal to one half. 389 * 390 * @return a new {@code MutableDecimal17f} value initialised with 0.5. 391 */ 392 public static MutableDecimal17f half() { 393 return new MutableDecimal17f(Decimal17f.HALF); 394 } 395 396 /** 397 * Returns a new {@code MutableDecimal17f} whose value is equal to one tenth. 398 * 399 * @return a new {@code MutableDecimal17f} value initialised with 0.1. 400 */ 401 public static MutableDecimal17f tenth() { 402 return new MutableDecimal17f(Decimal17f.TENTH); 403 } 404 405 /** 406 * Returns a new {@code MutableDecimal17f} whose value is equal to one hundredth. 407 * 408 * @return a new {@code MutableDecimal17f} value initialised with 0.01. 409 */ 410 public static MutableDecimal17f hundredth() { 411 return new MutableDecimal17f(Decimal17f.HUNDREDTH); 412 } 413 414 /** 415 * Returns a new {@code MutableDecimal17f} whose value is equal to one thousandth. 416 * 417 * @return a new {@code MutableDecimal17f} value initialised with 0.001. 418 */ 419 public static MutableDecimal17f thousandth() { 420 return new MutableDecimal17f(Decimal17f.THOUSANDTH); 421 } 422 423 /** 424 * Returns a new {@code MutableDecimal17f} whose value is equal to one millionth. 425 * 426 * @return a new {@code MutableDecimal17f} value initialised with 10<sup>-6</sup>. 427 */ 428 public static MutableDecimal17f millionth() { 429 return new MutableDecimal17f(Decimal17f.MILLIONTH); 430 } 431 432 /** 433 * Returns a new {@code MutableDecimal17f} whose value is equal to one billionth. 434 * 435 * @return a new {@code MutableDecimal17f} value initialised with 10<sup>-9</sup>. 436 */ 437 public static MutableDecimal17f billionth() { 438 return new MutableDecimal17f(Decimal17f.BILLIONTH); 439 } 440 441 /** 442 * Returns a new {@code MutableDecimal17f} whose value is equal to one trillionth. 443 * 444 * @return a new {@code MutableDecimal17f} value initialised with 10<sup>-12</sup>. 445 */ 446 public static MutableDecimal17f trillionth() { 447 return new MutableDecimal17f(Decimal17f.TRILLIONTH); 448 } 449 450 /** 451 * Returns a new {@code MutableDecimal17f} whose value is equal to one quadrillionth. 452 * 453 * @return a new {@code MutableDecimal17f} value initialised with 10<sup>-15</sup>. 454 */ 455 public static MutableDecimal17f quadrillionth() { 456 return new MutableDecimal17f(Decimal17f.QUADRILLIONTH); 457 } 458 459 460 /** 461 * Returns this {@code Decimal} as a multipliable factor for exact 462 * typed exact multiplication. The second factor is passed to one of 463 * the {@code by(..)} methods of the returned multiplier. The scale of 464 * the result is the sum of the scales of {@code this} Decimal and the 465 * second factor passed to the {@code by(..)} method. 466 * <p> 467 * The method is similar to {@link #multiplyExact(Decimal) multiplyExact(Decimal)} but the result 468 * is retrieved in exact typed form with the correct result scale. 469 * <p> 470 * For instance one can write: 471 * <pre> 472 * Decimal17f product = this.multiplyExact().by(Decimal0f.FIVE); 473 * </pre> 474 * 475 * @return a multipliable object encapsulating this Decimal as first factor 476 * of an exact multiplication 477 */ 478 public Multipliable17f multiplyExact() { 479 return new Multipliable17f(this); 480 } 481 482 @Override 483 public Decimal17f toImmutableDecimal() { 484 return Decimal17f.valueOf(this); 485 } 486 487 @Override 488 public MutableDecimal17f toMutableDecimal() { 489 return this; 490 } 491}