001/** 002 * The MIT License (MIT) 003 * 004 * Copyright (c) 2015-2016 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.base; 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.api.ImmutableDecimal; 033import org.decimal4j.api.MutableDecimal; 034import org.decimal4j.scale.ScaleMetrics; 035import org.decimal4j.truncate.CheckedRounding; 036import org.decimal4j.truncate.OverflowMode; 037import org.decimal4j.truncate.TruncationPolicy; 038import org.decimal4j.truncate.UncheckedRounding; 039 040/** 041 * Common base class for {@link AbstractImmutableDecimal immutable} and 042 * {@link AbstractMutableDecimal mutable} {@link Decimal} numbers of different 043 * scales. 044 * 045 * @param <S> 046 * the scale metrics type associated with this decimal 047 * @param <D> 048 * the concrete class implementing this decimal 049 */ 050@SuppressWarnings("serial") 051abstract public class AbstractDecimal<S extends ScaleMetrics, D extends AbstractDecimal<S, D>> 052 extends Number implements Decimal<S> { 053 054 /** 055 * Returns this or a new {@code Decimal} whose value is 056 * <tt>(unscaled × 10<sup>-scale</sup>)</tt>. 057 * <p> 058 * The returned value is a new instance if this decimal is an 059 * {@link ImmutableDecimal}. If it is a {@link MutableDecimal} then its 060 * internal state is altered and {@code this} is returned as result now 061 * representing <tt>(unscaled × 10<sup>-scale</sup>)</tt>. 062 * 063 * @param unscaled 064 * unscaled value to be returned as a {@code Decimal} 065 * @return <tt>unscaled × 10<sup>-scale</sup></tt> 066 */ 067 abstract protected D createOrAssign(long unscaled); 068 069 /** 070 * Returns a new {@code Decimal} whose value is 071 * <tt>(unscaled × 10<sup>-scale</sup>)</tt>. 072 * 073 * @param unscaled 074 * unscaled value to be returned as a {@code Decimal} 075 * @return <tt>unscaled × 10<sup>-scale</sup></tt> 076 */ 077 abstract protected D create(long unscaled); 078 079 /** 080 * Returns a new {@code Decimal} array of the specified {@code length}. 081 * 082 * @param length 083 * the length of the array to return 084 * @return {@code new D[length]} 085 */ 086 abstract protected D[] createArray(int length); 087 088 /** 089 * Returns {@code this} decimal value as concrete implementation subtype. 090 * 091 * @return {@code this} 092 */ 093 abstract protected D self(); 094 095 /** 096 * Returns the default arithmetic performing unchecked operations with 097 * rounding mode {@link RoundingMode#HALF_UP HALF_UP}. 098 * 099 * @return default arithmetic with {@link RoundingMode#HALF_UP HALF_UP} 100 * rounding and {@link OverflowMode#UNCHECKED UNCHECKED} overflow 101 * mode 102 */ 103 protected DecimalArithmetic getDefaultArithmetic() { 104 return getScaleMetrics().getDefaultArithmetic(); 105 } 106 107 /** 108 * Returns the default arithmetic performing checked operations with 109 * rounding mode {@link RoundingMode#HALF_UP HALF_UP}. 110 * 111 * @return default arithmetic with {@link RoundingMode#HALF_UP HALF_UP} 112 * rounding and {@link OverflowMode#CHECKED CHECKED} overflow mode 113 */ 114 protected DecimalArithmetic getDefaultCheckedArithmetic() { 115 return getScaleMetrics().getDefaultCheckedArithmetic(); 116 } 117 118 /** 119 * Returns the default arithmetic performing checked operations with 120 * rounding mode {@link RoundingMode#HALF_UP HALF_UP} and the specified 121 * {@code overflowMode}. 122 * 123 * @param overflowMode 124 * the overflow for the returned arithmetic 125 * 126 * @return default arithmetic with {@link RoundingMode#HALF_UP HALF_UP} 127 * rounding and the given {@code overflowMode} 128 */ 129 protected DecimalArithmetic getArithmeticFor(OverflowMode overflowMode) { 130 return getScaleMetrics().getArithmetic(overflowMode == OverflowMode.CHECKED ? CheckedRounding.HALF_UP : UncheckedRounding.HALF_UP); 131 } 132 133 /** 134 * Returns the arithmetic performing unchecked operations with rounding mode 135 * {@link RoundingMode#DOWN DOWN}. 136 * 137 * @return arithmetic with {@link RoundingMode#DOWN DOWN} rounding and 138 * {@link OverflowMode#UNCHECKED UNCHECKED} overflow mode 139 */ 140 protected DecimalArithmetic getRoundingDownArithmetic() { 141 return getScaleMetrics().getRoundingDownArithmetic(); 142 } 143 144 /** 145 * Returns the arithmetic performing unchecked operations with rounding mode 146 * {@link RoundingMode#FLOOR FLOOR}. 147 * 148 * @return arithmetic with {@link RoundingMode#FLOOR FLOOR} rounding and 149 * {@link OverflowMode#UNCHECKED UNCHECKED} overflow mode 150 */ 151 protected DecimalArithmetic getRoundingFloorArithmetic() { 152 return getScaleMetrics().getRoundingFloorArithmetic(); 153 } 154 155 /** 156 * Returns the arithmetic performing unchecked operations with rounding mode 157 * {@link RoundingMode#HALF_EVEN HALF_EVEN}. 158 * 159 * @return arithmetic with {@link RoundingMode#HALF_UP HALF_UP} rounding and 160 * {@link OverflowMode#UNCHECKED UNCHECKED} overflow mode 161 */ 162 protected DecimalArithmetic getRoundingHalfEvenArithmetic() { 163 return getScaleMetrics().getRoundingHalfEvenArithmetic(); 164 } 165 166 /** 167 * Returns the arithmetic performing unchecked operations with rounding mode 168 * {@link RoundingMode#UNNECESSARY UNNECESSARY}. 169 * 170 * @return arithmetic with {@link RoundingMode#UNNECESSARY UNNECESSARY} 171 * rounding and {@link OverflowMode#UNCHECKED UNCHECKED} overflow 172 * mode 173 */ 174 protected DecimalArithmetic getRoundingUnnecessaryArithmetic() { 175 return getScaleMetrics().getRoundingUnnecessaryArithmetic(); 176 } 177 178 /** 179 * Returns the arithmetic performing unchecked operations with the specified 180 * {@link RoundingMode}. 181 * 182 * @param roundingMode 183 * the rounding for the returned arithmetic 184 * @return arithmetic with specified {@code roundingMode} and 185 * {@link OverflowMode#UNCHECKED UNCHECKED} overflow mode 186 */ 187 protected DecimalArithmetic getArithmeticFor(RoundingMode roundingMode) { 188 return getScaleMetrics().getArithmetic(roundingMode); 189 } 190 191 /** 192 * Returns the arithmetic performing checked operations with the specified 193 * {@link RoundingMode}. 194 * 195 * @param roundingMode 196 * the rounding for the returned arithmetic 197 * @return arithmetic with specified {@code roundingMode} and 198 * {@link OverflowMode#CHECKED CHECKED} overflow mode 199 */ 200 protected DecimalArithmetic getCheckedArithmeticFor(RoundingMode roundingMode) { 201 return getScaleMetrics().getCheckedArithmetic(roundingMode); 202 } 203 204 /** 205 * Returns the arithmetic for the specified {@code truncationPolicy}. 206 * 207 * @param truncationPolicy 208 * the truncation policy for the returned arithmetic 209 * @return arithmetic performing operations according to the given 210 * {@code truncationPolicy} 211 */ 212 protected DecimalArithmetic getArithmeticFor(TruncationPolicy truncationPolicy) { 213 return getScaleMetrics().getArithmetic(truncationPolicy); 214 } 215 216 /* -------------------- Number and simular conversion ------------------- */ 217 218 @Override 219 public byte byteValueExact() { 220 final long num = longValueExact(); // will check decimal part 221 if ((byte) num != num) { 222 throw new ArithmeticException("Overflow: " + num + " is out of the possible range for a byte"); 223 } 224 return (byte) num; 225 } 226 227 @Override 228 public short shortValueExact() { 229 final long num = longValueExact(); // will check decimal part 230 if ((short) num != num) { 231 throw new ArithmeticException("Overflow: " + num + " is out of the possible range for a short"); 232 } 233 return (short) num; 234 } 235 236 @Override 237 public int intValue() { 238 return (int) longValue(); 239 } 240 241 @Override 242 public int intValueExact() { 243 final long num = longValueExact(); // will check decimal part 244 if ((int) num != num) { 245 throw new ArithmeticException("Overflow: " + num + " is out of the possible range for an int"); 246 } 247 return (int) num; 248 } 249 250 @Override 251 public long longValue() { 252 return getRoundingDownArithmetic().toLong(unscaledValue()); 253 } 254 255 @Override 256 public long longValueExact() { 257 return getRoundingUnnecessaryArithmetic().toLong(unscaledValue()); 258 } 259 260 @Override 261 public long longValue(RoundingMode roundingMode) { 262 return getArithmeticFor(roundingMode).toLong(unscaledValue()); 263 } 264 265 @Override 266 public float floatValue() { 267 // NOTE: Must be HALF_EVEN rounding mode according to The Java Language 268 // Specification 269 // @see section 5.1.3 narrowing primitive conversion 270 // @see section 4.2.3. Floating-Point Types, Formats, and Values 271 // @see IEEE 754-1985 Standard for Binary Floating-Point Arithmetic 272 return getRoundingHalfEvenArithmetic().toFloat(unscaledValue()); 273 } 274 275 @Override 276 public float floatValue(RoundingMode roundingMode) { 277 return getArithmeticFor(roundingMode).toFloat(unscaledValue()); 278 } 279 280 @Override 281 public double doubleValue() { 282 // NOTE: Must be HALF_EVEN rounding mode according to The Java Language 283 // Specification 284 // @see section 5.1.3 narrowing primitive conversion 285 // @see section 4.2.3. Floating-Point Types, Formats, and Values 286 // @see IEEE 754-1985 Standard for Binary Floating-Point Arithmetic 287 return getRoundingHalfEvenArithmetic().toDouble(unscaledValue()); 288 } 289 290 @Override 291 public double doubleValue(RoundingMode roundingMode) { 292 return getArithmeticFor(roundingMode).toDouble(unscaledValue()); 293 } 294 295 @Override 296 public BigInteger toBigInteger() { 297 return BigInteger.valueOf(longValue()); 298 } 299 300 @Override 301 public BigInteger toBigIntegerExact() { 302 return BigInteger.valueOf(longValueExact()); 303 } 304 305 @Override 306 public BigInteger toBigInteger(RoundingMode roundingMode) { 307 return BigInteger.valueOf(longValue(roundingMode)); 308 } 309 310 @Override 311 public BigDecimal toBigDecimal() { 312 return getDefaultArithmetic().toBigDecimal(unscaledValue()); 313 } 314 315 @Override 316 public BigDecimal toBigDecimal(int scale, RoundingMode roundingMode) { 317 return getArithmeticFor(roundingMode).toBigDecimal(unscaledValue(), scale); 318 } 319 320 @Override 321 public D integralPart() { 322 final long unscaled = unscaledValue(); 323 final long integral = unscaled - getScaleMetrics().moduloByScaleFactor(unscaled); 324 return createOrAssign(integral); 325 } 326 327 @Override 328 public D fractionalPart() { 329 return createOrAssign(getScaleMetrics().moduloByScaleFactor(unscaledValue())); 330 } 331 332 /* ----------------------------- rounding ------------------------------ */ 333 @Override 334 public D round(int precision) { 335 if (precision < getScale()) { 336 return createOrAssign(getDefaultArithmetic().round(unscaledValue(), precision)); 337 } 338 return self(); 339 } 340 341 @Override 342 public D round(int precision, RoundingMode roundingMode) { 343 if (precision < getScale()) { 344 return createOrAssign(getArithmeticFor(roundingMode).round(unscaledValue(), precision)); 345 } 346 return self(); 347 } 348 349 @Override 350 public D round(int precision, TruncationPolicy truncationPolicy) { 351 if (precision < getScale()) { 352 return createOrAssign(getArithmeticFor(truncationPolicy).round(unscaledValue(), precision)); 353 } 354 return self(); 355 } 356 357 /* -------------------------------- add -------------------------------- */ 358 359 @Override 360 public D add(Decimal<S> augend) { 361 return addUnscaled(augend.unscaledValue()); 362 } 363 364 @Override 365 public D add(Decimal<S> augend, OverflowMode overflowMode) { 366 return addUnscaled(augend.unscaledValue(), overflowMode); 367 } 368 369 @Override 370 public D add(Decimal<?> augend, RoundingMode roundingMode) { 371 return addUnscaled(augend.unscaledValue(), augend.getScale(), roundingMode); 372 } 373 374 @Override 375 public D add(Decimal<?> augend, TruncationPolicy truncationPolicy) { 376 return addUnscaled(augend.unscaledValue(), augend.getScale(), truncationPolicy); 377 } 378 379 @Override 380 public D add(long augend) { 381 return createOrAssign(getDefaultArithmetic().addLong(unscaledValue(), augend)); 382 } 383 384 @Override 385 public D add(long augend, OverflowMode overflowMode) { 386 return createOrAssign(getArithmeticFor(overflowMode).addLong(unscaledValue(), augend)); 387 } 388 389 @Override 390 public D add(double augend) { 391 final DecimalArithmetic arith = getDefaultCheckedArithmetic(); 392 return createOrAssign(arith.add(unscaledValue(), arith.fromDouble(augend))); 393 } 394 395 @Override 396 public D add(double augend, RoundingMode roundingMode) { 397 final DecimalArithmetic arith = getCheckedArithmeticFor(roundingMode); 398 return createOrAssign(arith.add(unscaledValue(), arith.fromDouble(augend))); 399 } 400 401 @Override 402 public D addUnscaled(long unscaledAugend) { 403 final DecimalArithmetic arith = getDefaultArithmetic(); 404 return createOrAssign(arith.add(unscaledValue(), unscaledAugend)); 405 } 406 407 @Override 408 public D addUnscaled(long unscaledAugend, OverflowMode overflowMode) { 409 final DecimalArithmetic arith = getArithmeticFor(overflowMode); 410 return createOrAssign(arith.add(unscaledValue(), unscaledAugend)); 411 } 412 413 @Override 414 public D addUnscaled(long unscaledAugend, int scale) { 415 final DecimalArithmetic arith = getDefaultArithmetic(); 416 return createOrAssign(arith.addUnscaled(unscaledValue(), unscaledAugend, scale)); 417 } 418 419 @Override 420 public D addUnscaled(long unscaledAugend, int scale, RoundingMode roundingMode) { 421 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 422 return createOrAssign(arith.addUnscaled(unscaledValue(), unscaledAugend, scale)); 423 } 424 425 @Override 426 public D addUnscaled(long unscaledAugend, int scale, TruncationPolicy truncationPolicy) { 427 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 428 return createOrAssign(arith.addUnscaled(unscaledValue(), unscaledAugend, scale)); 429 } 430 431 @Override 432 public D addSquared(Decimal<S> value) { 433 final DecimalArithmetic arith = getDefaultArithmetic(); 434 return createOrAssign(arith.add(unscaledValue(), arith.square(value.unscaledValue()))); 435 } 436 437 @Override 438 public D addSquared(Decimal<S> value, RoundingMode roundingMode) { 439 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 440 return createOrAssign(arith.add(unscaledValue(), arith.square(value.unscaledValue()))); 441 } 442 443 @Override 444 public D addSquared(Decimal<S> value, TruncationPolicy truncationPolicy) { 445 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 446 return createOrAssign(arith.add(unscaledValue(), arith.square(value.unscaledValue()))); 447 } 448 449 /* ------------------------------ subtract ------------------------------ */ 450 451 @Override 452 public D subtract(Decimal<S> subtrahend) { 453 return subtractUnscaled(subtrahend.unscaledValue()); 454 } 455 456 @Override 457 public D subtract(Decimal<S> subtrahend, OverflowMode overflowMode) { 458 return subtractUnscaled(subtrahend.unscaledValue(), overflowMode); 459 } 460 461 @Override 462 public D subtract(Decimal<?> subtrahend, RoundingMode roundingMode) { 463 return subtractUnscaled(subtrahend.unscaledValue(), subtrahend.getScale(), roundingMode); 464 } 465 466 @Override 467 public D subtract(Decimal<?> subtrahend, TruncationPolicy truncationPolicy) { 468 return subtractUnscaled(subtrahend.unscaledValue(), subtrahend.getScale(), truncationPolicy); 469 } 470 471 @Override 472 public D subtract(long subtrahend) { 473 return createOrAssign(getDefaultArithmetic().subtractLong(unscaledValue(), subtrahend)); 474 } 475 476 @Override 477 public D subtract(long subtrahend, OverflowMode overflowMode) { 478 return createOrAssign(getArithmeticFor(overflowMode).subtractLong(unscaledValue(), subtrahend)); 479 } 480 481 @Override 482 public D subtract(double subtrahend) { 483 final DecimalArithmetic arith = getDefaultCheckedArithmetic(); 484 return createOrAssign(arith.subtract(unscaledValue(), arith.fromDouble(subtrahend))); 485 } 486 487 @Override 488 public D subtract(double subtrahend, RoundingMode roundingMode) { 489 final DecimalArithmetic arith = getCheckedArithmeticFor(roundingMode); 490 return createOrAssign(arith.subtract(unscaledValue(), arith.fromDouble(subtrahend))); 491 } 492 493 @Override 494 public D subtractUnscaled(long unscaledSubtrahend) { 495 final DecimalArithmetic arith = getDefaultArithmetic(); 496 return createOrAssign(arith.subtract(unscaledValue(), unscaledSubtrahend)); 497 } 498 499 @Override 500 public D subtractUnscaled(long unscaledSubtrahend, OverflowMode overflowMode) { 501 final DecimalArithmetic arith = getArithmeticFor(overflowMode); 502 return createOrAssign(arith.subtract(unscaledValue(), unscaledSubtrahend)); 503 } 504 505 @Override 506 public D subtractUnscaled(long unscaledSubtrahend, int scale) { 507 final DecimalArithmetic arith = getDefaultArithmetic(); 508 return createOrAssign(arith.subtractUnscaled(unscaledValue(), unscaledSubtrahend, scale)); 509 } 510 511 @Override 512 public D subtractUnscaled(long unscaledSubtrahend, int scale, RoundingMode roundingMode) { 513 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 514 return createOrAssign(arith.subtractUnscaled(unscaledValue(), unscaledSubtrahend, scale)); 515 } 516 517 @Override 518 public D subtractUnscaled(long unscaledSubtrahend, int scale, TruncationPolicy truncationPolicy) { 519 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 520 return createOrAssign(arith.subtractUnscaled(unscaledValue(), unscaledSubtrahend, scale)); 521 } 522 523 @Override 524 public D subtractSquared(Decimal<S> value) { 525 final DecimalArithmetic arith = getDefaultArithmetic(); 526 return createOrAssign(arith.subtract(unscaledValue(), arith.square(value.unscaledValue()))); 527 } 528 529 @Override 530 public D subtractSquared(Decimal<S> value, RoundingMode roundingMode) { 531 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 532 return createOrAssign(arith.subtract(unscaledValue(), arith.square(value.unscaledValue()))); 533 } 534 535 @Override 536 public D subtractSquared(Decimal<S> value, TruncationPolicy truncationPolicy) { 537 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 538 return createOrAssign(arith.subtract(unscaledValue(), arith.square(value.unscaledValue()))); 539 } 540 541 /* ------------------------------ multiply ------------------------------ */ 542 543 @Override 544 public D multiply(Decimal<S> multiplicand) { 545 return multiplyUnscaled(multiplicand.unscaledValue()); 546 } 547 548 @Override 549 public D multiply(Decimal<S> multiplicand, RoundingMode roundingMode) { 550 return multiplyUnscaled(multiplicand.unscaledValue(), roundingMode); 551 } 552 553 @Override 554 public D multiply(Decimal<S> multiplicand, TruncationPolicy truncationPolicy) { 555 return multiplyUnscaled(multiplicand.unscaledValue(), truncationPolicy); 556 } 557 558 @Override 559 public D multiplyBy(Decimal<?> multiplicand) { 560 return multiplyUnscaled(multiplicand.unscaledValue(), multiplicand.getScale()); 561 } 562 563 @Override 564 public D multiplyBy(Decimal<?> multiplicand, RoundingMode roundingMode) { 565 return multiplyUnscaled(multiplicand.unscaledValue(), multiplicand.getScale(), roundingMode); 566 } 567 568 @Override 569 public D multiplyBy(Decimal<?> multiplicand, TruncationPolicy truncationPolicy) { 570 return multiplyUnscaled(multiplicand.unscaledValue(), multiplicand.getScale(), truncationPolicy); 571 } 572 573 @Override 574 public D multiply(long multiplicand) { 575 final DecimalArithmetic arith = getDefaultArithmetic(); 576 return createOrAssign(arith.multiplyByLong(unscaledValue(), multiplicand)); 577 } 578 579 @Override 580 public D multiply(long multiplicand, OverflowMode overflowMode) { 581 final DecimalArithmetic arith = getArithmeticFor(overflowMode); 582 return createOrAssign(arith.multiplyByLong(unscaledValue(), multiplicand)); 583 } 584 585 @Override 586 public D multiply(double multiplicand) { 587 final DecimalArithmetic arith = getDefaultCheckedArithmetic(); 588 return createOrAssign(arith.multiply(unscaledValue(), arith.fromDouble(multiplicand))); 589 } 590 591 @Override 592 public D multiply(double multiplicand, RoundingMode roundingMode) { 593 final DecimalArithmetic arith = getCheckedArithmeticFor(roundingMode); 594 return createOrAssign(arith.multiply(unscaledValue(), arith.fromDouble(multiplicand))); 595 } 596 597 @Override 598 public D multiplyUnscaled(long unscaledMultiplicand) { 599 final DecimalArithmetic arith = getDefaultArithmetic(); 600 return createOrAssign(arith.multiply(unscaledValue(), unscaledMultiplicand)); 601 } 602 603 @Override 604 public D multiplyUnscaled(long unscaledMultiplicand, RoundingMode roundingMode) { 605 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 606 return createOrAssign(arith.multiply(unscaledValue(), unscaledMultiplicand)); 607 } 608 609 @Override 610 public D multiplyUnscaled(long unscaledMultiplicand, TruncationPolicy truncationPolicy) { 611 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 612 return createOrAssign(arith.multiply(unscaledValue(), unscaledMultiplicand)); 613 } 614 615 @Override 616 public D multiplyUnscaled(long unscaledMultiplicand, int scale) { 617 final DecimalArithmetic arith = getDefaultArithmetic(); 618 return createOrAssign(arith.multiplyByUnscaled(unscaledValue(), unscaledMultiplicand, scale)); 619 } 620 621 @Override 622 public D multiplyUnscaled(long unscaledMultiplicand, int scale, RoundingMode roundingMode) { 623 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 624 return createOrAssign(arith.multiplyByUnscaled(unscaledValue(), unscaledMultiplicand, scale)); 625 } 626 627 @Override 628 public D multiplyUnscaled(long unscaledMultiplicand, int scale, TruncationPolicy truncationPolicy) { 629 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 630 return createOrAssign(arith.multiplyByUnscaled(unscaledValue(), unscaledMultiplicand, scale)); 631 } 632 633 @Override 634 public D multiplyByPowerOfTen(int n) { 635 return createOrAssign(getDefaultArithmetic().multiplyByPowerOf10(unscaledValue(), n)); 636 } 637 638 @Override 639 public D multiplyByPowerOfTen(int n, RoundingMode roundingMode) { 640 return createOrAssign(getArithmeticFor(roundingMode).multiplyByPowerOf10(unscaledValue(), n)); 641 } 642 643 @Override 644 public D multiplyByPowerOfTen(int n, TruncationPolicy truncationPolicy) { 645 return createOrAssign(getArithmeticFor(truncationPolicy).multiplyByPowerOf10(unscaledValue(), n)); 646 } 647 648 /* ------------------------------ divide ------------------------------ */ 649 650 @Override 651 public D divide(Decimal<S> divisor) { 652 return divideUnscaled(divisor.unscaledValue()); 653 } 654 655 @Override 656 public D divide(Decimal<S> divisor, RoundingMode roundingMode) { 657 return divideUnscaled(divisor.unscaledValue(), roundingMode); 658 } 659 660 @Override 661 public D divide(Decimal<S> divisor, TruncationPolicy truncationPolicy) { 662 return divideUnscaled(divisor.unscaledValue(), truncationPolicy); 663 } 664 665 @Override 666 public D divideBy(Decimal<?> divisor) { 667 return divideUnscaled(divisor.unscaledValue(), divisor.getScale()); 668 } 669 670 @Override 671 public D divideBy(Decimal<?> divisor, RoundingMode roundingMode) { 672 return divideUnscaled(divisor.unscaledValue(), divisor.getScale(), roundingMode); 673 } 674 675 @Override 676 public D divideBy(Decimal<?> divisor, TruncationPolicy truncationPolicy) { 677 return divideUnscaled(divisor.unscaledValue(), divisor.getScale(), truncationPolicy); 678 } 679 680 @Override 681 public D divide(long divisor) { 682 final DecimalArithmetic arith = getDefaultArithmetic(); 683 return createOrAssign(arith.divideByLong(unscaledValue(), divisor)); 684 } 685 686 @Override 687 public D divide(long divisor, RoundingMode roundingMode) { 688 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 689 return createOrAssign(arith.divideByLong(unscaledValue(), divisor)); 690 } 691 692 @Override 693 public D divide(long divisor, TruncationPolicy truncationPolicy) { 694 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 695 return createOrAssign(arith.divideByLong(unscaledValue(), divisor)); 696 } 697 698 @Override 699 public D divide(double divisor) { 700 final DecimalArithmetic arith = getDefaultCheckedArithmetic(); 701 return createOrAssign(arith.divide(unscaledValue(), arith.fromDouble(divisor))); 702 } 703 704 @Override 705 public D divide(double divisor, RoundingMode roundingMode) { 706 final DecimalArithmetic arith = getCheckedArithmeticFor(roundingMode); 707 return createOrAssign(arith.divide(unscaledValue(), arith.fromDouble(divisor))); 708 } 709 710 @Override 711 public D divideUnscaled(long unscaledDivisor) { 712 final DecimalArithmetic arith = getDefaultArithmetic(); 713 return createOrAssign(arith.divide(unscaledValue(), unscaledDivisor)); 714 } 715 716 @Override 717 public D divideUnscaled(long unscaledDivisor, RoundingMode roundingMode) { 718 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 719 return createOrAssign(arith.divide(unscaledValue(), unscaledDivisor)); 720 } 721 722 @Override 723 public D divideUnscaled(long unscaledDivisor, TruncationPolicy truncationPolicy) { 724 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 725 return createOrAssign(arith.divide(unscaledValue(), unscaledDivisor)); 726 } 727 728 @Override 729 public D divideUnscaled(long unscaledDivisor, int scale) { 730 final DecimalArithmetic arith = getDefaultArithmetic(); 731 return createOrAssign(arith.divideByUnscaled(unscaledValue(), unscaledDivisor, scale)); 732 } 733 734 @Override 735 public D divideUnscaled(long unscaledDivisor, int scale, RoundingMode roundingMode) { 736 final DecimalArithmetic arith = getArithmeticFor(roundingMode); 737 return createOrAssign(arith.divideByUnscaled(unscaledValue(), unscaledDivisor, scale)); 738 } 739 740 @Override 741 public D divideUnscaled(long unscaledDivisor, int scale, TruncationPolicy truncationPolicy) { 742 final DecimalArithmetic arith = getArithmeticFor(truncationPolicy); 743 return createOrAssign(arith.divideByUnscaled(unscaledValue(), unscaledDivisor, scale)); 744 } 745 746 @Override 747 public D divideExact(Decimal<S> divisor) { 748 return divide(divisor, CheckedRounding.UNNECESSARY); 749 } 750 751 @Override 752 public D divideTruncate(Decimal<S> divisor) { 753 return createOrAssign(getRoundingDownArithmetic().divide(unscaledValue(), divisor.unscaledValue())); 754 } 755 756 @Override 757 public D divideByPowerOfTen(int n) { 758 return createOrAssign(getDefaultArithmetic().divideByPowerOf10(unscaledValue(), n)); 759 } 760 761 @Override 762 public D divideByPowerOfTen(int n, RoundingMode roundingMode) { 763 return createOrAssign(getArithmeticFor(roundingMode).divideByPowerOf10(unscaledValue(), n)); 764 } 765 766 @Override 767 public D divideByPowerOfTen(int n, TruncationPolicy truncationPolicy) { 768 return createOrAssign(getArithmeticFor(truncationPolicy).divideByPowerOf10(unscaledValue(), n)); 769 } 770 771 @Override 772 public D divideToIntegralValue(Decimal<S> divisor) { 773 final long longValue = unscaledValue() / divisor.unscaledValue(); 774 return createOrAssign(getScaleMetrics().multiplyByScaleFactor(longValue)); 775 } 776 777 @Override 778 public D divideToIntegralValue(Decimal<S> divisor, OverflowMode overflowMode) { 779 if (!overflowMode.isChecked()) { 780 return divideToIntegralValue(divisor); 781 } 782 final long longValue = divideToLongValue(divisor, overflowMode); 783 return createOrAssign(getScaleMetrics().multiplyByScaleFactorExact(longValue)); 784 } 785 786 @Override 787 public long divideToLongValue(Decimal<S> divisor) { 788 return unscaledValue() / divisor.unscaledValue(); 789 } 790 791 @Override 792 public long divideToLongValue(Decimal<S> divisor, OverflowMode overflowMode) { 793 final DecimalArithmetic arith = getArithmeticFor(overflowMode == OverflowMode.CHECKED ? CheckedRounding.DOWN : UncheckedRounding.DOWN); 794 try { 795 return arith.divideByLong(unscaledValue(), divisor.unscaledValue()); 796 } catch (ArithmeticException e) { 797 if (divisor.isZero()) { 798 throw new ArithmeticException("Division by zero: integral(" + this + " / " + divisor + ")"); 799 } 800 throw new ArithmeticException("Overflow: integral(" + this + " / " + divisor + ")"); 801 } 802 } 803 804 @Override 805 public D[] divideAndRemainder(Decimal<S> divisor) { 806 final long uDividend = unscaledValue(); 807 final long uDivisor = divisor.unscaledValue(); 808 final long lIntegral = uDividend / uDivisor; 809 final long uIntegral = getScaleMetrics().multiplyByScaleFactor(lIntegral); 810 final long uReminder = uDividend - uDivisor * lIntegral; 811 final D[] result = createArray(2); 812 result[0] = create(uIntegral); 813 result[1] = create(uReminder); 814 return result; 815 } 816 817 @Override 818 public D[] divideAndRemainder(Decimal<S> divisor, OverflowMode overflowMode) { 819 if (!overflowMode.isChecked()) { 820 return divideAndRemainder(divisor); 821 } 822 try { 823 final DecimalArithmetic arith = getArithmeticFor(CheckedRounding.DOWN); 824 final long uDividend = unscaledValue(); 825 final long uDivisor = divisor.unscaledValue(); 826 final long lIntegral = arith.divideByLong(uDividend, uDivisor); 827 final long uIntegral = getScaleMetrics().multiplyByScaleFactorExact(lIntegral); 828 final long uReminder = uDividend - uDivisor * lIntegral; 829 final D[] result = createArray(2); 830 result[0] = create(uIntegral); 831 result[1] = create(uReminder); 832 return result; 833 } catch (ArithmeticException e) { 834 if (divisor.isZero()) { 835 throw new ArithmeticException("Division by zero: integral(" + this + " / " + divisor + ")"); 836 } 837 throw new ArithmeticException("Overflow: integral(" + this + " / " + divisor + ")"); 838 } 839 } 840 841 @Override 842 public D remainder(Decimal<S> divisor) { 843 return createOrAssign(unscaledValue() % divisor.unscaledValue()); 844 } 845 846 /* ------------------------- other arithmetic ------------------------- */ 847 848 @Override 849 public int signum() { 850 return Long.signum(unscaledValue()); 851 } 852 853 @Override 854 public D negate() { 855 return createOrAssign(getDefaultArithmetic().negate(unscaledValue())); 856 } 857 858 @Override 859 public D negate(OverflowMode overflowMode) { 860 return createOrAssign(getArithmeticFor(overflowMode).negate(unscaledValue())); 861 } 862 863 @Override 864 public D abs() { 865 final long unscaled = unscaledValue(); 866 return unscaled >= 0 ? self() : createOrAssign(getDefaultArithmetic().negate(unscaled)); 867 } 868 869 @Override 870 public D abs(OverflowMode overflowMode) { 871 final long unscaled = unscaledValue(); 872 return unscaled >= 0 ? self() : createOrAssign(getArithmeticFor(overflowMode).negate(unscaled)); 873 } 874 875 @Override 876 public D invert() { 877 return createOrAssign(getDefaultArithmetic().invert(unscaledValue())); 878 } 879 880 @Override 881 public D invert(RoundingMode roundingMode) { 882 return createOrAssign(getArithmeticFor(roundingMode).invert(unscaledValue())); 883 } 884 885 @Override 886 public D invert(TruncationPolicy truncationPolicy) { 887 return createOrAssign(getArithmeticFor(truncationPolicy).invert(unscaledValue())); 888 } 889 890 @Override 891 public D square() { 892 return createOrAssign(getDefaultArithmetic().square(unscaledValue())); 893 } 894 895 @Override 896 public D square(RoundingMode roundingMode) { 897 return createOrAssign(getArithmeticFor(roundingMode).square(unscaledValue())); 898 } 899 900 @Override 901 public D square(TruncationPolicy truncationPolicy) { 902 return createOrAssign(getArithmeticFor(truncationPolicy).square(unscaledValue())); 903 } 904 905 @Override 906 public D sqrt() { 907 return createOrAssign(getDefaultArithmetic().sqrt(unscaledValue())); 908 } 909 910 @Override 911 public D sqrt(RoundingMode roundingMode) { 912 return createOrAssign(getArithmeticFor(roundingMode).sqrt(unscaledValue())); 913 } 914 915 @Override 916 public D shiftLeft(int n) { 917 // NOTE: FLOOR is default for shift! 918 return createOrAssign(getRoundingFloorArithmetic().shiftLeft(unscaledValue(), n)); 919 } 920 921 @Override 922 public D shiftLeft(int n, RoundingMode roundingMode) { 923 return createOrAssign(getArithmeticFor(roundingMode).shiftLeft(unscaledValue(), n)); 924 } 925 926 @Override 927 public D shiftLeft(int n, TruncationPolicy truncationPolicy) { 928 return createOrAssign(getArithmeticFor(truncationPolicy).shiftLeft(unscaledValue(), n)); 929 } 930 931 @Override 932 public D shiftRight(int n) { 933 // NOTE: FLOOR is default for shift! 934 return createOrAssign(getRoundingFloorArithmetic().shiftRight(unscaledValue(), n)); 935 } 936 937 @Override 938 public D shiftRight(int n, RoundingMode roundingMode) { 939 return createOrAssign(getArithmeticFor(roundingMode).shiftRight(unscaledValue(), n)); 940 } 941 942 @Override 943 public D shiftRight(int n, TruncationPolicy truncationPolicy) { 944 return createOrAssign(getArithmeticFor(truncationPolicy).shiftRight(unscaledValue(), n)); 945 } 946 947 @Override 948 public D pow(int n) { 949 return createOrAssign(getDefaultArithmetic().pow(unscaledValue(), n)); 950 } 951 952 @Override 953 public D pow(int n, RoundingMode roundingMode) { 954 return createOrAssign(getArithmeticFor(roundingMode).pow(unscaledValue(), n)); 955 } 956 957 @Override 958 public D pow(int n, TruncationPolicy truncationPolicy) { 959 return createOrAssign(getArithmeticFor(truncationPolicy).pow(unscaledValue(), n)); 960 } 961 962 /* --------------------------- compare etc. ---------------------------- */ 963 964 @Override 965 public int compareTo(Decimal<S> other) { 966 return getDefaultArithmetic().compare(unscaledValue(), other.unscaledValue()); 967 } 968 969 @Override 970 public boolean isEqualTo(Decimal<S> other) { 971 return compareTo(other) == 0; 972 } 973 974 @Override 975 public boolean isGreaterThan(Decimal<S> other) { 976 return compareTo(other) > 0; 977 } 978 979 @Override 980 public boolean isGreaterThanOrEqualTo(Decimal<S> other) { 981 return compareTo(other) >= 0; 982 } 983 984 @Override 985 public boolean isLessThan(Decimal<S> other) { 986 return compareTo(other) < 0; 987 } 988 989 @Override 990 public boolean isLessThanOrEqualTo(Decimal<S> other) { 991 return compareTo(other) <= 0; 992 } 993 994 @Override 995 public boolean isZero() { 996 return unscaledValue() == 0; 997 } 998 999 @Override 1000 public boolean isOne() { 1001 return unscaledValue() == getScaleMetrics().getScaleFactor(); 1002 } 1003 1004 @Override 1005 public boolean isUlp() { 1006 return unscaledValue() == 1; 1007 } 1008 1009 @Override 1010 public boolean isMinusOne() { 1011 return unscaledValue() == -getScaleMetrics().getScaleFactor(); 1012 } 1013 1014 @Override 1015 public boolean isPositive() { 1016 return unscaledValue() > 0; 1017 } 1018 1019 @Override 1020 public boolean isNonNegative() { 1021 return unscaledValue() >= 0; 1022 } 1023 1024 @Override 1025 public boolean isNegative() { 1026 return unscaledValue() < 0; 1027 } 1028 1029 @Override 1030 public boolean isNonPositive() { 1031 return unscaledValue() <= 0; 1032 } 1033 1034 @Override 1035 public boolean isIntegral() { 1036 return getScaleMetrics().moduloByScaleFactor(unscaledValue()) == 0; 1037 } 1038 1039 @Override 1040 public boolean isIntegralPartZero() { 1041 final long unscaled = unscaledValue(); 1042 final long one = getScaleMetrics().getScaleFactor(); 1043 return one > unscaled & unscaled > -one; 1044 } 1045 1046 @Override 1047 public boolean isBetweenZeroAndOne() { 1048 final long unscaled = unscaledValue(); 1049 return 0 <= unscaled && unscaled < getScaleMetrics().getScaleFactor(); 1050 } 1051 1052 @Override 1053 public boolean isBetweenZeroAndMinusOne() { 1054 final long unscaled = unscaledValue(); 1055 return 0 >= unscaled && unscaled > -(getScaleMetrics().getScaleFactor()); 1056 } 1057 1058 @Override 1059 public int compareToNumerically(Decimal<?> other) { 1060 return getDefaultArithmetic().compareToUnscaled(unscaledValue(), other.unscaledValue(), other.getScale()); 1061 } 1062 1063 @Override 1064 public boolean isEqualToNumerically(Decimal<?> other) { 1065 return compareToNumerically(other) == 0; 1066 } 1067 1068 @Override 1069 public Decimal<S> min(Decimal<S> val) { 1070 return isLessThanOrEqualTo(val) ? this : val; 1071 } 1072 1073 @Override 1074 public Decimal<S> max(Decimal<S> val) { 1075 return isGreaterThanOrEqualTo(val) ? this : val; 1076 } 1077 1078 /** 1079 * Returns the minimum of this {@code Decimal} and {@code val}. 1080 * 1081 * @param val 1082 * value with which the minimum is to be computed. 1083 * @return the {@code Decimal} whose value is the lesser of this 1084 * {@code Decimal} and {@code val}. If they are equal, as defined by 1085 * the {@link #compareTo(Decimal) compareTo} method, {@code this} is 1086 * returned. 1087 * @see #compareTo(Decimal) 1088 */ 1089 public D min(D val) { 1090 return isLessThanOrEqualTo(val) ? self() : val; 1091 } 1092 1093 /** 1094 * Returns the maximum of this {@code Decimal} and {@code val}. 1095 * 1096 * @param val 1097 * value with which the maximum is to be computed. 1098 * @return the {@code Decimal} whose value is the greater of this 1099 * {@code Decimal} and {@code val}. If they are equal, as defined by 1100 * the {@link #compareTo(Decimal) compareTo} method, {@code this} is 1101 * returned. 1102 * @see #compareTo(Decimal) 1103 */ 1104 public D max(D val) { 1105 return isGreaterThanOrEqualTo(val) ? self() : val; 1106 } 1107 1108 @Override 1109 public D avg(Decimal<S> val) { 1110 return createOrAssign(getDefaultArithmetic().avg(unscaledValue(), val.unscaledValue())); 1111 } 1112 1113 @Override 1114 public D avg(Decimal<S> val, RoundingMode roundingMode) { 1115 return createOrAssign(getArithmeticFor(roundingMode).avg(unscaledValue(), val.unscaledValue())); 1116 } 1117 1118 /* ---------------------------- equals etc. ---------------------------- */ 1119 1120 @Override 1121 public int hashCode() { 1122 final long unscaled = unscaledValue(); 1123 long hash = getScale(); 1124 hash = 31 * hash + (unscaled >>> 32); 1125 hash = 31 * hash + unscaled; 1126 return (int) hash; 1127 } 1128 1129 @Override 1130 public boolean equals(Object obj) { 1131 if (obj instanceof Decimal) { 1132 final Decimal<?> other = (Decimal<?>) obj; 1133 return unscaledValue() == other.unscaledValue() && getScale() == other.getScale(); 1134 } 1135 return false; 1136 } 1137 1138 @Override 1139 public String toString() { 1140 return getDefaultArithmetic().toString(unscaledValue()); 1141 } 1142}