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.immutable; 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.AbstractImmutableDecimal; 033import org.decimal4j.exact.Multipliable18f; 034import org.decimal4j.factory.Factory18f; 035import org.decimal4j.mutable.MutableDecimal18f; 036import org.decimal4j.scale.Scale18f; 037 038/** 039 * <code>Decimal18f</code> represents an immutable decimal number with a fixed 040 * number of 18 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 Decimal18f extends AbstractImmutableDecimal<Scale18f, Decimal18f> { 046 047 private static final long serialVersionUID = 1L; 048 049 /** Scale value 18 for {@code Decimal18f} returned by {@link #getScale()}.*/ 050 public static final int SCALE = 18; 051 052 /** Scale metrics constant for {@code Decimal18f} returned by {@link #getScaleMetrics()}.*/ 053 public static final Scale18f METRICS = Scale18f.INSTANCE; 054 055 /** Factory constant for {@code Decimal18f} returned by {@link #getFactory()}.*/ 056 public static final Factory18f FACTORY = Factory18f.INSTANCE; 057 058 /** 059 * Default arithmetic for {@code Decimal18f} performing unchecked operations with rounding mode 060 * {@link RoundingMode#HALF_UP HALF_UP}. 061 */ 062 public static final DecimalArithmetic DEFAULT_ARITHMETIC = METRICS.getDefaultArithmetic(); 063 064 /** 065 * Default arithmetic for {@code Decimal18f} performing checked operations with rounding mode 066 * {@link RoundingMode#HALF_UP HALF_UP}. 067 */ 068 public static final DecimalArithmetic DEFAULT_CHECKED_ARITHMETIC = METRICS.getDefaultCheckedArithmetic(); 069 070 /** The unscaled long value that represents one.*/ 071 public static final long ONE_UNSCALED = METRICS.getScaleFactor(); 072 073 /** The {@code Decimal18f} constant zero.*/ 074 public static final Decimal18f ZERO = new Decimal18f(0); 075 /** 076 * A constant holding the smallest positive value a {@code Decimal18f} 077 * can have, 10<sup>-18</sup>. 078 */ 079 public static final Decimal18f ULP = new Decimal18f(1); 080 081 /** 082 * Initialize static constant array when class is loaded. 083 */ 084 private static final int MAX_CONSTANT = 9; 085 private static final Decimal18f POS_CONST[] = new Decimal18f[MAX_CONSTANT+1]; 086 private static final Decimal18f NEG_CONST[] = new Decimal18f[MAX_CONSTANT+1]; 087 088 static { 089 for (int i = 1; i <= MAX_CONSTANT; i++) { 090 POS_CONST[i] = new Decimal18f(ONE_UNSCALED * i); 091 NEG_CONST[i] = new Decimal18f(-ONE_UNSCALED * i); 092 } 093 } 094 095 /** The {@code Decimal18f} constant 1.*/ 096 public static final Decimal18f ONE = valueOf(1); 097 /** The {@code Decimal18f} constant 2.*/ 098 public static final Decimal18f TWO = valueOf(2); 099 /** The {@code Decimal18f} constant 3.*/ 100 public static final Decimal18f THREE = valueOf(3); 101 /** The {@code Decimal18f} constant 4.*/ 102 public static final Decimal18f FOUR = valueOf(4); 103 /** The {@code Decimal18f} constant 5.*/ 104 public static final Decimal18f FIVE = valueOf(5); 105 /** The {@code Decimal18f} constant 6.*/ 106 public static final Decimal18f SIX = valueOf(6); 107 /** The {@code Decimal18f} constant 7.*/ 108 public static final Decimal18f SEVEN = valueOf(7); 109 /** The {@code Decimal18f} constant 8.*/ 110 public static final Decimal18f EIGHT = valueOf(8); 111 /** The {@code Decimal18f} constant 9.*/ 112 public static final Decimal18f NINE = valueOf(9); 113 114 /** The {@code Decimal18f} constant -1.*/ 115 public static final Decimal18f MINUS_ONE = valueOf(-1); 116 117 /** The {@code Decimal18f} constant 0.5.*/ 118 public static final Decimal18f HALF = new Decimal18f(ONE_UNSCALED / 2); 119 /** The {@code Decimal18f} constant 0.1.*/ 120 public static final Decimal18f TENTH = new Decimal18f(ONE_UNSCALED / 10); 121 /** The {@code Decimal18f} constant 0.01.*/ 122 public static final Decimal18f HUNDREDTH = new Decimal18f(ONE_UNSCALED / 100); 123 /** The {@code Decimal18f} constant 0.001.*/ 124 public static final Decimal18f THOUSANDTH = new Decimal18f(ONE_UNSCALED / 1000); 125 /** The {@code Decimal18f} constant 10<sup>-6</sup>.*/ 126 public static final Decimal18f MILLIONTH = new Decimal18f(ONE_UNSCALED / 1000000); 127 /** The {@code Decimal18f} constant 10<sup>-9</sup>.*/ 128 public static final Decimal18f BILLIONTH = new Decimal18f(ONE_UNSCALED / 1000000000); 129 /** The {@code Decimal18f} constant 10<sup>-12</sup>.*/ 130 public static final Decimal18f TRILLIONTH = new Decimal18f(ONE_UNSCALED / 1000000000000L); 131 /** The {@code Decimal18f} constant 10<sup>-15</sup>.*/ 132 public static final Decimal18f QUADRILLIONTH = new Decimal18f(ONE_UNSCALED / 1000000000000000L); 133 /** The {@code Decimal18f} constant 10<sup>-18</sup>.*/ 134 public static final Decimal18f QUINTILLIONTH = new Decimal18f(ONE_UNSCALED / 1000000000000000000L); 135 136 /** 137 * A constant holding the maximum value a {@code Decimal18f} can have, 138 * 9.223372036854775807. 139 */ 140 public static final Decimal18f MAX_VALUE = new Decimal18f(Long.MAX_VALUE); 141 /** 142 * A constant holding the maximum integer value a {@code Decimal18f} 143 * can have, 9.000000000000000000. 144 */ 145 public static final Decimal18f MAX_INTEGER_VALUE = new Decimal18f((Long.MAX_VALUE / ONE_UNSCALED) * ONE_UNSCALED); 146 /** 147 * A constant holding the minimum value a {@code Decimal18f} can have, 148 * -9.223372036854775808. 149 */ 150 public static final Decimal18f MIN_VALUE = new Decimal18f(Long.MIN_VALUE); 151 /** 152 * A constant holding the minimum integer value a {@code Decimal18f} 153 * can have, -9.000000000000000000. 154 */ 155 public static final Decimal18f MIN_INTEGER_VALUE = new Decimal18f((Long.MIN_VALUE / ONE_UNSCALED) * ONE_UNSCALED); 156 157 /** 158 * Private constructor with unscaled value. 159 * 160 * @param unscaled the unscaled value 161 */ 162 private Decimal18f(long unscaled) { 163 super(unscaled); 164 } 165 166 /** 167 * Translates the string representation of a {@code Decimal} into a 168 * {@code Decimal18f}. The string representation consists of an 169 * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of 170 * zero or more decimal digits ("the integer"), optionally followed by a 171 * fraction. 172 * <p> 173 * The fraction consists of a decimal point followed by zero or more decimal 174 * digits. The string must contain at least one digit in either the integer 175 * or the fraction. If the fraction contains more than 18 digits, the 176 * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An 177 * exception is thrown if the value is too large to be represented as a 178 * {@code Decimal18f}. 179 * 180 * @param value 181 * String value to convert into a {@code Decimal18f} 182 * @throws NumberFormatException 183 * if {@code value} does not represent a valid {@code Decimal} 184 * or if the value is too large to be represented as a 185 * {@code Decimal18f} 186 */ 187 public Decimal18f(String value) { 188 super(DEFAULT_CHECKED_ARITHMETIC.parse(value)); 189 } 190 191 @Override 192 public final Scale18f getScaleMetrics() { 193 return METRICS; 194 } 195 196 @Override 197 public final int getScale() { 198 return SCALE; 199 } 200 201 @Override 202 public final Factory18f getFactory() { 203 return FACTORY; 204 } 205 206 @Override 207 protected final Decimal18f self() { 208 return this; 209 } 210 211 @Override 212 protected final DecimalArithmetic getDefaultArithmetic() { 213 return DEFAULT_ARITHMETIC; 214 } 215 216 @Override 217 protected final DecimalArithmetic getDefaultCheckedArithmetic() { 218 return DEFAULT_CHECKED_ARITHMETIC; 219 } 220 221 @Override 222 protected final DecimalArithmetic getRoundingDownArithmetic() { 223 return METRICS.getRoundingDownArithmetic(); 224 } 225 226 @Override 227 protected final DecimalArithmetic getRoundingFloorArithmetic() { 228 return METRICS.getRoundingFloorArithmetic(); 229 } 230 231 @Override 232 protected final DecimalArithmetic getRoundingHalfEvenArithmetic() { 233 return METRICS.getRoundingHalfEvenArithmetic(); 234 } 235 236 @Override 237 protected final DecimalArithmetic getRoundingUnnecessaryArithmetic() { 238 return METRICS.getRoundingUnnecessaryArithmetic(); 239 } 240 241 /** 242 * Returns a {@code Decimal18f} whose value is numerically equal to 243 * that of the specified {@code long} value. An exception is thrown if the 244 * specified value is too large to be represented as a {@code Decimal18f}. 245 * 246 * @param value 247 * long value to convert into a {@code Decimal18f} 248 * @return a {@code Decimal18f} value numerically equal to the specified 249 * {@code long} value 250 * @throws IllegalArgumentException 251 * if {@code value} is too large to be represented as a 252 * {@code Decimal18f} 253 */ 254 public static Decimal18f valueOf(long value) { 255 if (value == 0) 256 return ZERO; 257 if (value > 0 & value <= MAX_CONSTANT) 258 return POS_CONST[(int) value]; 259 else if (value < 0 & value >= -MAX_CONSTANT) 260 return NEG_CONST[(int) -value]; 261 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromLong(value)); 262 } 263 264 /** 265 * Returns a {@code Decimal18f} whose value is calculated by 266 * rounding the specified {@code float} argument to scale 18 267 * using {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown 268 * if the specified value is too large to be represented as a {@code Decimal18f}. 269 * 270 * @param value 271 * float value to convert into a {@code Decimal18f} 272 * @return a {@code Decimal18f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code> 273 * @throws IllegalArgumentException 274 * if {@code value} is NaN or infinite or if the magnitude is 275 * too large for the float to be represented as a {@code Decimal18f} 276 */ 277 public static Decimal18f valueOf(float value) { 278 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromFloat(value)); 279 } 280 281 /** 282 * Returns a {@code Decimal18f} whose value is calculated by 283 * rounding the specified {@code float} argument to scale 18 284 * using the specified {@code roundingMode}. An exception is thrown 285 * if the specified value is too large to be represented as a {@code Decimal18f}. 286 * 287 * @param value 288 * float value to convert into a {@code Decimal18f} 289 * @param roundingMode 290 * the rounding mode to apply during the conversion if necessary 291 * @return a {@code Decimal18f} calculated as: <code>round(value)</code> 292 * @throws IllegalArgumentException 293 * if {@code value} is NaN or infinite or if the magnitude is 294 * too large for the float to be represented as a {@code Decimal18f} 295 * @throws ArithmeticException 296 * if {@code roundingMode==UNNECESSARY} and rounding is 297 * necessary 298 */ 299 public static Decimal18f valueOf(float value, RoundingMode roundingMode) { 300 return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromFloat(value)); 301 } 302 303 /** 304 * Returns a {@code Decimal18f} whose value is calculated by 305 * rounding the specified {@code double} argument to scale 18 306 * using {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown 307 * if the specified value is too large to be represented as a {@code Decimal18f}. 308 * 309 * @param value 310 * double value to convert into a {@code Decimal18f} 311 * @return a {@code Decimal18f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code> 312 * @throws IllegalArgumentException 313 * if {@code value} is NaN or infinite or if the magnitude is 314 * too large for the double to be represented as a {@code Decimal18f} 315 */ 316 public static Decimal18f valueOf(double value) { 317 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromDouble(value)); 318 } 319 320 /** 321 * Returns a {@code Decimal18f} whose value is calculated by 322 * rounding the specified {@code double} argument to scale 18 323 * using the specified {@code roundingMode}. An exception is thrown 324 * if the specified value is too large to be represented as a {@code Decimal18f}. 325 * 326 * @param value 327 * double value to convert into a {@code Decimal18f} 328 * @param roundingMode 329 * the rounding mode to apply during the conversion if necessary 330 * @return a {@code Decimal18f} calculated as: <code>round(value)</code> 331 * @throws IllegalArgumentException 332 * if {@code value} is NaN or infinite or if the magnitude is 333 * too large for the double to be represented as a {@code Decimal18f} 334 * @throws ArithmeticException 335 * if {@code roundingMode==UNNECESSARY} and rounding is 336 * necessary 337 */ 338 public static Decimal18f valueOf(double value, RoundingMode roundingMode) { 339 return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromDouble(value)); 340 } 341 342 /** 343 * Returns a {@code Decimal18f} whose value is numerically equal to that of 344 * the specified {@link BigInteger} value. An exception is thrown if the 345 * specified value is too large to be represented as a {@code Decimal18f}. 346 * 347 * @param value 348 * {@code BigInteger} value to convert into a {@code Decimal18f} 349 * @return a {@code Decimal18f} value numerically equal to the specified big 350 * integer value 351 * @throws IllegalArgumentException 352 * if {@code value} is too large to be represented as a {@code Decimal18f} 353 */ 354 public static Decimal18f valueOf(BigInteger value) { 355 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromBigInteger(value)); 356 } 357 358 /** 359 * Returns a {@code Decimal18f} whose value is calculated by rounding 360 * the specified {@link BigDecimal} argument to scale 18 using 361 * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the 362 * specified value is too large to be represented as a {@code Decimal18f}. 363 * 364 * @param value 365 * {@code BigDecimal} value to convert into a {@code Decimal18f} 366 * @return a {@code Decimal18f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code> 367 * @throws IllegalArgumentException 368 * if {@code value} is too large to be represented as a {@code Decimal18f} 369 */ 370 public static Decimal18f valueOf(BigDecimal value) { 371 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromBigDecimal(value)); 372 } 373 374 /** 375 * Returns a {@code Decimal18f} whose value is calculated by rounding 376 * the specified {@link BigDecimal} argument to scale 18 using 377 * the specified {@code roundingMode}. An exception is thrown if the 378 * specified value is too large to be represented as a {@code Decimal18f}. 379 * 380 * @param value 381 * {@code BigDecimal} value to convert into a {@code Decimal18f} 382 * @param roundingMode 383 * the rounding mode to apply during the conversion if necessary 384 * @return a {@code Decimal18f} calculated as: <code>round(value)</code> 385 * @throws IllegalArgumentException 386 * if {@code value} is too large to be represented as a {@code Decimal18f} 387 * @throws ArithmeticException 388 * if {@code roundingMode==UNNECESSARY} and rounding is 389 * necessary 390 */ 391 public static Decimal18f valueOf(BigDecimal value, RoundingMode roundingMode) { 392 return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromBigDecimal(value)); 393 } 394 395 /** 396 * Returns a {@code Decimal18f} whose value is calculated by rounding 397 * the specified {@link Decimal} argument to scale 18 using 398 * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the 399 * specified value is too large to be represented as a {@code Decimal18f}. 400 * 401 * @param value 402 * Decimal value to convert into a {@code Decimal18f} 403 * @return a {@code Decimal18f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code> 404 * @throws IllegalArgumentException 405 * if {@code value} is too large to be represented as a {@code Decimal18f} 406 */ 407 public static Decimal18f valueOf(Decimal<?> value) { 408 if (value instanceof Decimal18f) { 409 return (Decimal18f)value; 410 } 411 return valueOfUnscaled(value.unscaledValue(), value.getScale()); 412 } 413 414 /** 415 * Returns a {@code Decimal18f} whose value is calculated by rounding 416 * the specified {@link Decimal} argument to scale 18 using 417 * the specified {@code roundingMode}. An exception is thrown if the 418 * specified value is too large to be represented as a {@code Decimal18f}. 419 * 420 * @param value 421 * Decimal value to convert into a {@code Decimal18f} 422 * @param roundingMode 423 * the rounding mode to apply during the conversion if necessary 424 * @return a {@code Decimal18f} calculated as: <code>round(value)</code> 425 * @throws IllegalArgumentException 426 * if {@code value} is too large to be represented as a {@code Decimal18f} 427 * @throws ArithmeticException 428 * if {@code roundingMode==UNNECESSARY} and rounding is 429 * necessary 430 */ 431 public static Decimal18f valueOf(Decimal<?> value, RoundingMode roundingMode) { 432 if (value instanceof Decimal18f) { 433 return (Decimal18f)value; 434 } 435 return valueOfUnscaled(value.unscaledValue(), value.getScale(), roundingMode); 436 } 437 438 /** 439 * Translates the string representation of a {@code Decimal} into a 440 * {@code Decimal18f}. The string representation consists of an 441 * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of 442 * zero or more decimal digits ("the integer"), optionally followed by a 443 * fraction. 444 * <p> 445 * The fraction consists of a decimal point followed by zero or more decimal 446 * digits. The string must contain at least one digit in either the integer 447 * or the fraction. If the fraction contains more than 18 digits, the 448 * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An 449 * exception is thrown if the value is too large to be represented as a 450 * {@code Decimal18f}. 451 * 452 * @param value 453 * String value to convert into a {@code Decimal18f} 454 * @return a {@code Decimal18f} calculated as: <code>round<sub>HALF_UP</sub>(value)</code> 455 * @throws NumberFormatException 456 * if {@code value} does not represent a valid {@code Decimal} 457 * or if the value is too large to be represented as a 458 * {@code Decimal18f} 459 */ 460 public static Decimal18f valueOf(String value) { 461 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.parse(value)); 462 } 463 464 /** 465 * Translates the string representation of a {@code Decimal} into a 466 * {@code Decimal18f}. The string representation consists of an 467 * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of 468 * zero or more decimal digits ("the integer"), optionally followed by a 469 * fraction. 470 * <p> 471 * The fraction consists of a decimal point followed by zero or more decimal 472 * digits. The string must contain at least one digit in either the integer 473 * or the fraction. If the fraction contains more than 18 digits, the 474 * value is rounded using the specified {@code roundingMode}. An exception 475 * is thrown if the value is too large to be represented as a {@code Decimal18f}. 476 * 477 * @param value 478 * String value to convert into a {@code Decimal18f} 479 * @param roundingMode 480 * the rounding mode to apply if the fraction contains more than 481 * 18 digits 482 * @return a {@code Decimal18f} calculated as: <code>round(value)</code> 483 * @throws NumberFormatException 484 * if {@code value} does not represent a valid {@code Decimal} 485 * or if the value is too large to be represented as a 486 * {@code Decimal18f} 487 * @throws ArithmeticException 488 * if {@code roundingMode==UNNECESSARY} and rounding is 489 * necessary 490 */ 491 public static Decimal18f valueOf(String value, RoundingMode roundingMode) { 492 return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).parse(value)); 493 } 494 495 /** 496 * Returns a {@code Decimal18f} whose value is numerically equal to 497 * <code>(unscaledValue × 10<sup>-18</sup>)</code>. 498 * 499 * @param unscaledValue 500 * unscaled value to convert into a {@code Decimal18f} 501 * @return a {@code Decimal18f} calculated as: 502 * <code>unscaledValue × 10<sup>-18</sup></code> 503 */ 504 public static Decimal18f valueOfUnscaled(long unscaledValue) { 505 if (unscaledValue == 0) { 506 return ZERO; 507 } 508 if (unscaledValue == 1) { 509 return ULP; 510 } 511 if (unscaledValue == ONE_UNSCALED) { 512 return ONE; 513 } 514 if (unscaledValue == -ONE_UNSCALED) { 515 return MINUS_ONE; 516 } 517 return new Decimal18f(unscaledValue); 518 } 519 520 /** 521 * Returns a {@code Decimal18f} whose value is numerically equal to 522 * <code>(unscaledValue × 10<sup>-scale</sup>)</code>. The result is 523 * rounded to scale 18 using {@link RoundingMode#HALF_UP HALF_UP} 524 * rounding. An exception is thrown if the specified value is too large 525 * to be represented as a {@code Decimal18f}. 526 * 527 * @param unscaledValue 528 * unscaled value to convert into a {@code Decimal18f} 529 * @param scale 530 * the scale to apply to {@code unscaledValue} 531 * @return a {@code Decimal18f} calculated as: 532 * <code>round<sub>HALF_UP</sub>(unscaledValue × 10<sup>-scale</sup>)</code> 533 * @throws IllegalArgumentException 534 * if the specified value is too large to be represented as a 535 * {@code Decimal18f} 536 */ 537 public static Decimal18f valueOfUnscaled(long unscaledValue, int scale) { 538 return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromUnscaled(unscaledValue, scale)); 539 } 540 541 /** 542 * Returns a {@code Decimal18f} whose value is numerically equal to 543 * <code>(unscaledValue × 10<sup>-scale</sup>)</code>. The result 544 * is rounded to scale 18 using the specified {@code roundingMode}. 545 * An exception is thrown if the specified value is too large to be 546 * represented as a {@code Decimal18f}. 547 * 548 * @param unscaledValue 549 * unscaled value to convert into a Decimal18 550 * @param scale 551 * the scale to apply to {@code unscaledValue} 552 * @param roundingMode 553 * the rounding mode to apply during the conversion if necessary 554 * @return a {@code Decimal18f} calculated as: 555 * <code>round(unscaledValue × 10<sup>-scale</sup>)</code> 556 * @throws IllegalArgumentException 557 * if the specified value is too large to be represented as a {@code Decimal18f} 558 */ 559 public static Decimal18f valueOfUnscaled(long unscaledValue, int scale, RoundingMode roundingMode) { 560 return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromUnscaled(unscaledValue, scale)); 561 } 562 563 @Override 564 protected Decimal18f createOrAssign(long unscaled) { 565 return valueOfUnscaled(unscaled); 566 } 567 568 @Override 569 protected Decimal18f create(long unscaled) { 570 return valueOfUnscaled(unscaled); 571 } 572 573 @Override 574 protected Decimal18f[] createArray(int length) { 575 return new Decimal18f[length]; 576 } 577 578 /** 579 * Returns this {@code Decimal} as a multipliable factor for typed 580 * exact multiplication. The second factor is passed to one of the 581 * {@code by(..)} methods of the returned multiplier. The scale of 582 * the result is the sum of the scales of {@code this} Decimal and the 583 * second factor passed to the {@code by(..)} method. 584 * <p> 585 * The method is similar to {@link #multiplyExact(Decimal) multiplyExact(Decimal)} but the result 586 * is retrieved in exact typed form with the correct result scale. 587 * <p> 588 * For instance one can write: 589 * <pre> 590 * Decimal18f product = this.multiplyExact().by(Decimal0f.FIVE); 591 * </pre> 592 * 593 * @return a multipliable object encapsulating this Decimal as first factor 594 * of an exact multiplication 595 */ 596 public Multipliable18f multiplyExact() { 597 return new Multipliable18f(this); 598 } 599 600 @Override 601 public MutableDecimal18f toMutableDecimal() { 602 return new MutableDecimal18f(this); 603 } 604 605 @Override 606 public Decimal18f toImmutableDecimal() { 607 return this; 608 } 609} 610