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.api; 025 026import java.io.IOException; 027import java.math.BigDecimal; 028import java.math.BigInteger; 029import java.math.RoundingMode; 030 031import org.decimal4j.scale.ScaleMetrics; 032import org.decimal4j.scale.Scales; 033import org.decimal4j.truncate.OverflowMode; 034import org.decimal4j.truncate.TruncationPolicy; 035 036/** 037 * <tt>DecimalArithmetic</tt> defines the basic primitive operations for {@link Decimal} numbers for one particular 038 * combination of {@link #getScale() scale}, {@link #getRoundingMode() rounding mode} and {@link #getOverflowMode() 039 * overflow mode}. Primitive here means that <tt>Decimal</tt> values are simply represented by their underlying unscaled 040 * <tt>long</tt> value. All operations therefore use unscaled longs for <tt>Decimal</tt> arguments and return longs for 041 * <tt>Decimal</tt> number results. 042 * <p> 043 * Application code does not usually need to use <tt>DecimalArithmetic</tt> directly. It may be appropriate however for 044 * very specialized applications with low latency, high frequency or zero garbage requirements. All operations of 045 * <tt>DecimalArithmetic</tt> do not allocate any objects (zero garbage) unless otherwise indicated. 046 */ 047public interface DecimalArithmetic { 048 /** 049 * Returns the scale {@code f} applied to all unscaled decimal values passed to and returned by this 050 * {@code DecimalArithmetic}. Corresponds to the number of digits to the right of the decimal point (cannot be 051 * negative). 052 * <p> 053 * A given {@link Decimal} value multiplied with <tt>10<sup>f</sup></tt> results in an unscaled long value. 054 * Conversely, a {@code Decimal} value {@code d} can be computed from the unscaled value {@code u} as 055 * <tt>d = u*10<sup>-f</sup></tt>. 056 * 057 * @return the non-negative scale {@code f} applied to unscaled decimal values within this {@code DecimalArithmetic} 058 * object 059 * @see ScaleMetrics#getScale() 060 */ 061 int getScale(); 062 063 /** 064 * Returns the scale metrics associated with this decimal arithmetic object. 065 * 066 * @return the scale metrics 067 */ 068 ScaleMetrics getScaleMetrics(); 069 070 /** 071 * Returns the <i>rounding mode</i> applied to operations of this {@code DecimalArithmetic} object if rounding is 072 * necessary. 073 * 074 * @return the rounding mode applied to operations of this {@code DecimalArithmetic} object if rounding is necessary 075 */ 076 RoundingMode getRoundingMode(); 077 078 /** 079 * Returns the <i>overflow mode</i> applied to operations of this {@code DecimalArithmetic} object if an overflow 080 * occurs. The overflow mode defines whether an operation should throw an exception if an overflow occurs. 081 * 082 * @return the overflow mode applied to operations of this {@code DecimalArithmetic} object if an overflow occurs 083 */ 084 OverflowMode getOverflowMode(); 085 086 /** 087 * Returns the <i>truncation policy</i> defining how to handle truncation due to overflow or rounding. The 088 * {@code TruncationPolicy} is defined by the {@link #getOverflowMode() overflow mode} and the 089 * {@link #getRoundingMode() rounding mode}. 090 * 091 * @return the truncation policy defining how this {@code DecimalArithmetic} handles truncation 092 */ 093 TruncationPolicy getTruncationPolicy(); 094 095 /** 096 * Derives an arithmetic instance for the specified {@code scale} using this arithmetic's {@link #getRoundingMode() 097 * rounding mode} and {@link #getOverflowMode() overflow mode}. 098 * 099 * @param scale 100 * the scale for the new arithmetic; must be in {@code [0,18]} both ends inclusive 101 * @return an arithmetic instance with the given scale and this arithmetic's rounding and overflow mode 102 * @throws IllegalArgumentException 103 * if scale is not in {@code [0, 18]} 104 * @see Scales#getScaleMetrics(int) 105 * @see ScaleMetrics#getArithmetic(RoundingMode) 106 * @see ScaleMetrics#getArithmetic(TruncationPolicy) 107 */ 108 DecimalArithmetic deriveArithmetic(int scale); 109 110 /** 111 * Derives an arithmetic instance for the same {@link #getScale() scale} as this arithmetic but for the specified 112 * {@code roundingMode}. The returned arithmetic uses the same {@link #getOverflowMode() overflow mode} as this 113 * arithmetic. 114 * 115 * @param roundingMode 116 * the rounding mode for the new arithmetic 117 * @return an arithmetic instance with the given rounding mode and this arithmetic's scale and overflow mode 118 * @throws NullPointerException 119 * if rounding mode is null 120 */ 121 DecimalArithmetic deriveArithmetic(RoundingMode roundingMode); 122 123 /** 124 * Derives an arithmetic instance for the same {@link #getScale() scale} as this arithmetic but for the specified 125 * {@code roundingMode} and {@code overflowMode}. 126 * 127 * @param roundingMode 128 * the rounding mode for the new arithmetic 129 * @param overflowMode 130 * the overflow mode for the new arithmetic 131 * @return an arithmetic instance with the given rounding and overflow mode and this arithmetic's scale 132 * @throws NullPointerException 133 * if any of the arguments is null 134 */ 135 DecimalArithmetic deriveArithmetic(RoundingMode roundingMode, OverflowMode overflowMode); 136 137 /** 138 * Derives an arithmetic instance for the same {@link #getScale() scale} as this arithmetic but for the specified 139 * {@code overflowMode}. The returned arithmetic uses the same {@link #getRoundingMode() rounding mode} as this 140 * arithmetic. 141 * 142 * @param overflowMode 143 * the overflow mode for the new arithmetic 144 * @return an arithmetic instance with the given overflow mode and this arithmetic's scale and rounding mode 145 * @throws NullPointerException 146 * if overflow mode is null 147 */ 148 DecimalArithmetic deriveArithmetic(OverflowMode overflowMode); 149 150 /** 151 * Derives an arithmetic instance for the same {@link #getScale() scale} as this arithmetic but with rounding and 152 * overflow mode specified by the given {@code truncationPolicy}. 153 * 154 * @param truncationPolicy 155 * the truncation policy specifying rounding and overflow mode for the new arithmetic 156 * @return an arithmetic instance with rounding and overflow mode specified by the truncation policy using this 157 * arithmetic's scale 158 * @throws NullPointerException 159 * if truncation policy is null 160 */ 161 DecimalArithmetic deriveArithmetic(TruncationPolicy truncationPolicy); 162 163 /** 164 * Returns the unscaled decimal for the decimal value {@code 1}. One is the value <tt>10<sup>scale</sup></tt> which 165 * is also the multiplier used to get the unscaled decimal from the true decimal value. 166 * 167 * @return the unscaled decimal representing the decimal value 1 168 */ 169 long one(); 170 171 /** 172 * Returns the signum function of the specified unscaled decimal. 173 * 174 * @param uDecimal 175 * the unscaled decimal 176 * @return -1, 0, or 1 as the value of the specified unscaled decimal is negative, zero, or positive. 177 */ 178 int signum(long uDecimal); 179 180 /** 181 * Compares two unscaled decimal values numerically. 182 * 183 * @param uDecimal1 184 * the first unscaled decimal to compare 185 * @param uDecimal2 186 * the second unscaled decimal to compare 187 * @return the value {@code 0} if {@code unscaled1 == unscaled2}; a value less than {@code 0} if 188 * {@code unscaled1 < unscaled2}; and a value greater than {@code 0} if {@code unscaled1 > unscaled2} 189 */ 190 int compare(long uDecimal1, long uDecimal2); 191 192 /** 193 * Compares two unscaled decimal values numerically. Note that scale of the first operand is determined by this 194 * arithmetic's {@link #getScale() scale} whereas the scale of the second {@code unscaled} value is explicitly 195 * specified by the {@code scale} argument. 196 * 197 * @param uDecimal 198 * the first unscaled decimal to compare 199 * @param unscaled 200 * the second unscaled decimal to compare 201 * @param scale 202 * the scale of {@code unscaled} 203 * @return the value {@code 0} if {@code unscaled1 == unscaled2}; a value less than {@code 0} if 204 * {@code unscaled1 < unscaled2}; and a value greater than {@code 0} if {@code unscaled1 > unscaled2} 205 */ 206 int compareToUnscaled(long uDecimal, long unscaled, int scale); 207 208 /** 209 * Returns an unscaled decimal whose value is {@code (uDecimal1 + uDecimal2)}. 210 * 211 * @param uDecimal1 212 * first unscaled decimal value to be added 213 * @param uDecimal2 214 * second unscaled decimal value to be added 215 * @return {@code uDecimal1 + uDecimal2} 216 * @throws ArithmeticException 217 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 218 */ 219 long add(long uDecimal1, long uDecimal2); 220 221 /** 222 * Returns an unscaled decimal whose value is the sum of the specified arguments: {@code (uDecimal + lValue)}. 223 * <p> 224 * Mathematically the method calculates <tt>(uDecimal + lValue * 10<sup>scale</sup>)</tt> avoiding information loss 225 * due to overflow of intermediary results. 226 * 227 * @param uDecimal 228 * unscaled decimal value to be added 229 * @param lValue 230 * long value to be added 231 * @return <tt>(uDecimal + lValue * 10<sup>scale</sup>)</tt> 232 * @throws ArithmeticException 233 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 234 */ 235 long addLong(long uDecimal, long lValue); 236 237 /** 238 * Returns an unscaled decimal whose value is <tt>(uDecimal + unscaled * 10<sup>-scale</sup>)</tt>. If rounding must 239 * be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. Note that scale of the first 240 * operand is determined by this arithmetic's {@link #getScale() scale} whereas the scale of the second 241 * {@code unscaled} value is explicitly specified by the {@code scale} argument. 242 * <p> 243 * Mathematically the method calculates <tt>round(uDecimal + lValue * 10<sup>-scale + s</sup>)</tt> where {@code s} 244 * refers to this arithetic's scale. The method avoids information loss due to overflow of intermediary results. 245 * 246 * @param uDecimal 247 * unscaled decimal value to be added to 248 * @param unscaled 249 * unscaled value to add 250 * @param scale 251 * scale associated with the {@code unscaled} value 252 * @return <tt>round(uDecimal + unscaled * 10<sup>-scale</sup>)</tt> 253 * @throws ArithmeticException 254 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 255 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 256 */ 257 long addUnscaled(long uDecimal, long unscaled, int scale); 258 259 /** 260 * Returns an unscaled decimal whose value is {@code (uDecimalMinuend - 261 * uDecimalSubtrahend)}. 262 * 263 * @param uDecimalMinuend 264 * unscaled decimal value to subtract from 265 * @param uDecimalSubtrahend 266 * unscaled decimal value to subtract from the minuend 267 * @return {@code uDecimalMinuend - uDecimalSubtrahend} 268 * @throws ArithmeticException 269 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 270 */ 271 long subtract(long uDecimalMinuend, long uDecimalSubtrahend); 272 273 /** 274 * Returns an unscaled decimal whose value is the difference of the specified arguments: {@code (uDecimal - lValue)} 275 * . 276 * <p> 277 * Mathematically the method calculates <tt>(uDecimal - lValue * 10<sup>scale</sup>)</tt> avoiding information loss 278 * due to overflow of intermediary results. 279 * 280 * @param uDecimal 281 * unscaled decimal value to subtract from 282 * @param lValue 283 * long value to subtract 284 * @return <tt>(uDecimal - lValue * 10<sup>scale</sup>)</tt> 285 * @throws ArithmeticException 286 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 287 */ 288 long subtractLong(long uDecimal, long lValue); 289 290 /** 291 * Returns an unscaled decimal whose value is <tt>(uDecimal - unscaled * 10<sup>-scale</sup>)</tt>. If rounding must 292 * be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. Note that scale of the first 293 * operand is determined by this arithmetic's {@link #getScale() scale} whereas the scale of the second 294 * {@code unscaled} value is explicitly specified by the {@code scale} argument. 295 * <p> 296 * Mathematically the method calculates <tt>round(uDecimal - lValue * 10<sup>-scale + s</sup>)</tt> where {@code s} 297 * refers to this arithetic's scale. The method avoids information loss due to overflow of intermediary results. 298 * 299 * @param uDecimal 300 * unscaled decimal value to subtract from 301 * @param unscaled 302 * unscaled value to subtract 303 * @param scale 304 * scale associated with the {@code unscaled} value 305 * @return <tt>round(uDecimal - unscaled * 10<sup>-scale</sup>)</tt> as unscaled decimal 306 * @throws ArithmeticException 307 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 308 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 309 */ 310 long subtractUnscaled(long uDecimal, long unscaled, int scale); 311 312 /** 313 * Returns an unscaled decimal whose value is the product of the specified arguments: 314 * {@code (uDecimal1 * uDecimal2)}. If rounding must be performed, this arithmetic's {@link #getRoundingMode() 315 * rounding mode} is applied. 316 * <p> 317 * Mathematically the method calculates <tt>round((uDecimal1 * uDecimal2) * 10<sup>-scale</sup>)</tt> avoiding 318 * information loss due to overflow of intermediary results. 319 * 320 * @param uDecimal1 321 * first unscaled decimal value to be multiplied 322 * @param uDecimal2 323 * second unscaled decimal value to be multiplied 324 * @return {@code round(uDecimal1 * uDecimal2)} 325 * @throws ArithmeticException 326 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 327 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 328 */ 329 long multiply(long uDecimal1, long uDecimal2); 330 331 /** 332 * Returns an unscaled decimal whose value is {@code (uDecimal * lValue)} where the second argument is a true long 333 * value instead of an unscaled decimal. 334 * 335 * @param uDecimal 336 * unscaled decimal value to be multiplied 337 * @param lValue 338 * long value to be multiplied 339 * @return {@code uDecimal * lValue} 340 * @throws ArithmeticException 341 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 342 */ 343 long multiplyByLong(long uDecimal, long lValue); 344 345 /** 346 * Returns an unscaled decimal whose value is <tt>(uDecimal * unscaled * 10<sup>-scale</sup>)</tt>. If rounding must 347 * be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. Note that scale of the first 348 * operand is determined by this arithmetic's {@link #getScale() scale} whereas the scale of the second 349 * {@code unscaled} value is explicitly specified by the {@code scale} argument. 350 * <p> 351 * Mathematically the method calculates <tt>round((uDecimal * unscaled) * 10<sup>-scale</sup>)</tt> avoiding 352 * information loss due to overflow of intermediary results. 353 * 354 * @param uDecimal 355 * unscaled decimal value to be multiplied 356 * @param unscaled 357 * unscaled value to be multiplied 358 * @param scale 359 * scale associated with the {@code unscaled} value 360 * @return <tt>round(uDecimal * (unscaled * 10<sup>-scale</sup>))</tt> 361 * @throws ArithmeticException 362 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 363 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 364 */ 365 long multiplyByUnscaled(long uDecimal, long unscaled, int scale); 366 367 /** 368 * Returns an unscaled decimal whose value is <tt>(uDecimal * 10<sup>n</sup>)</tt>. 369 * <p> 370 * The power, {@code n}, may be negative, in which case this method performs a division by a power of ten. If 371 * rounding must be performed (for negative n), this arithmetic's {@link #getRoundingMode() rounding mode} is 372 * applied. 373 * 374 * @param uDecimal 375 * value to be multiplied 376 * @param n 377 * the power of ten 378 * @return <tt>round(uDecimal × 10<sup>n</sup>)</tt> 379 * @throws ArithmeticException 380 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 381 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 382 */ 383 long multiplyByPowerOf10(long uDecimal, int n); 384 385 /** 386 * Returns an unscaled decimal whose value is the quotient of the specified arguments: 387 * {@code (uDecimalDividend / uDecimalDivisor)}. If rounding must be performed, this arithmetic's 388 * {@link #getRoundingMode() rounding mode} is applied. 389 * <p> 390 * Mathematically the method calculates <tt>round((uDecimalDividend * 10<sup>scale</sup>) / uDecimalDivisor)</tt> 391 * avoiding information loss due to overflow of intermediary results. 392 * 393 * @param uDecimalDividend 394 * value to be divided. 395 * @param uDecimalDivisor 396 * value by which the dividend is to be divided. 397 * @return {@code round(uDecimalDividend / uDecimalDivisor)} 398 * @throws ArithmeticException 399 * if {@code uDecimalDividend} is zero, if {@link #getRoundingMode() rounding mode} is UNNECESSARY and 400 * rounding is necessary or if an overflow occurs and the {@link #getOverflowMode() overflow mode} is 401 * set to throw an exception 402 */ 403 long divide(long uDecimalDividend, long uDecimalDivisor); 404 405 /** 406 * Returns an unscaled decimal whose value is {@code (uDecimalDividend / lDivisor)} where the second argument is a 407 * true long value instead of an unscaled decimal. If rounding must be performed, this arithmetic's 408 * {@link #getRoundingMode() rounding mode} is applied. 409 * 410 * @param uDecimalDividend 411 * value to be divided. 412 * @param lDivisor 413 * long value by which the dividend is to be divided. 414 * @return {@code round(uDecimalDividend / lDivisor)} 415 * @throws ArithmeticException 416 * if {@code uDecimalDividend} is zero, if {@link #getRoundingMode() rounding mode} is UNNECESSARY and 417 * rounding is necessary or if an overflow occurs and the {@link #getOverflowMode() overflow mode} is 418 * set to throw an exception 419 */ 420 long divideByLong(long uDecimalDividend, long lDivisor); 421 422 /** 423 * Returns an unscaled decimal whose value is <tt>(uDecimal / (unscaled * 10<sup>-scale</sup>))</tt>. If rounding 424 * must be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. Note that scale of the 425 * first operand is determined by this arithmetic's {@link #getScale() scale} whereas the scale of the second 426 * {@code unscaled} value is explicitly specified by the {@code scale} argument. 427 * <p> 428 * Mathematically the method calculates <tt>round((uDecimal * 10<sup>scale</sup>) / unscaled)</tt> avoiding 429 * information loss due to overflow of intermediary results. 430 * 431 * @param uDecimal 432 * value to be divided. 433 * @param unscaled 434 * unscaled value by which the dividend is to be divided. 435 * @param scale 436 * scale associated with the {@code unscaled} value 437 * @return <tt>round(uDecimal / (unscaled * 10<sup>-scale</sup>))</tt> 438 * @throws ArithmeticException 439 * if {@code uDecimal} is zero, if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding 440 * is necessary or if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to 441 * throw an exception 442 */ 443 long divideByUnscaled(long uDecimal, long unscaled, int scale); 444 445 /** 446 * Returns an unscaled decimal whose value is <tt>(uDecimal / 10<sup>n</sup>)</tt>. If rounding must be performed, 447 * this arithmetic's {@link #getRoundingMode() rounding mode} is applied. 448 * <p> 449 * The power, {@code n}, may be negative, in which case this method performs a multiplication by a power of ten. 450 * 451 * @param uDecimal 452 * value to be divided. 453 * @param n 454 * the power of ten 455 * @return <tt>round(uDecimal / 10<sup>n</sup>)</tt> 456 * @throws ArithmeticException 457 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 458 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 459 */ 460 long divideByPowerOf10(long uDecimal, int n); 461 462 /** 463 * Returns an unscaled decimal whose value is the average of {@code uDecimal1} and {@code uDecimal2}. The method is 464 * much more efficient than an addition and subsequent long division and is guaranteed not to overflow. If rounding 465 * must be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. 466 * 467 * @param uDecimal1 468 * the first unscaled decimal value to average 469 * @param uDecimal2 470 * the second unscaled decimal value to average 471 * @return {@code round((uDecimal1 + uDecimal2) / 2)} 472 * @throws ArithmeticException 473 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 474 */ 475 long avg(long uDecimal1, long uDecimal2); 476 477 /** 478 * Returns an unscaled decimal whose value is {@code abs(uDecimal)}, which is the value itself if 479 * {@code uDecimal>=0} and {@code -uDecimal} if the given value is negative. 480 * 481 * @param uDecimal 482 * the unscaled decimal value 483 * @return {@code abs(uDecimal)} 484 * @throws ArithmeticException 485 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 486 */ 487 long abs(long uDecimal); 488 489 /** 490 * Returns an unscaled decimal whose value is {@code -uDecimal}. 491 * 492 * @param uDecimal 493 * the unscaled decimal value to negate 494 * @return {@code -uDecimal} 495 * @throws ArithmeticException 496 * if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 497 */ 498 long negate(long uDecimal); 499 500 /** 501 * Returns an unscaled decimal whose value is the inverse of the argument: {@code 1/uDecimal}. If rounding must be 502 * performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. 503 * <p> 504 * Mathematically the method calculates <tt>round((10<sup>scale</sup> * 10<sup>scale</sup>) / uDecimalDivisor)</tt> 505 * avoiding information loss due to overflow of intermediary results. 506 * 507 * @param uDecimal 508 * the unscaled decimal value to invert 509 * @return {@code round(1/uDecimal)} 510 * @throws ArithmeticException 511 * if {@code uDecimal} is zero, if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding 512 * is necessary or if an overflow occurs and the {@link #getOverflowMode() overflow mode} is set to 513 * throw an exception 514 */ 515 long invert(long uDecimal); 516 517 /** 518 * Returns an unscaled decimal whose value is the square of the specified argument: <tt>uDecimal<sup>2</sup></tt>. 519 * If rounding must be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. 520 * <p> 521 * Mathematically the method calculates <tt>round((uDecimal * uDecimal) * 10<sup>-scale</sup>)</tt> avoiding 522 * information loss due to overflow of intermediary results. 523 * 524 * @param uDecimal 525 * the unscaled decimal value to be squared 526 * @return {@code round(uDecimal * uDecimal)} 527 * @throws ArithmeticException 528 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 529 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 530 */ 531 long square(long uDecimal); 532 533 /** 534 * Returns an unscaled decimal whose value is the square root of the specified argument: <tt>sqrt(uDecimal)</tt>. If 535 * rounding must be performed, this arithmetic's {@link #getRoundingMode() rounding mode} is applied. 536 * <p> 537 * Mathematically the method calculates <tt>round(sqrt(uDecimal * 10<sup>scale</sup>))</tt> avoiding information 538 * loss due to overflow of intermediary results. 539 * 540 * @param uDecimal 541 * the unscaled decimal value 542 * @return {@code round(sqrt(uDecimal))} 543 * @throws ArithmeticException 544 * if {@code uDecimal} is negative or if {@link #getRoundingMode() rounding mode} is UNNECESSARY and 545 * rounding is necessary 546 */ 547 long sqrt(long uDecimal); 548 549 /** 550 * Returns an unscaled decimal whose value is <tt>(uDecimalBase<sup>exponent</sup>)</tt>. Note that {@code exponent} 551 * is an integer rather than a decimal. If rounding must be performed, this arithmetic's {@link #getRoundingMode() 552 * rounding mode} is applied. 553 * <p> 554 * The current implementation uses the core algorithm defined in ANSI standard X3.274-1996. For {@code exponent >= 0}, the 555 * returned numerical value is within 1 ULP of the exact numerical value; the result is actually exact for all 556 * rounding modes other than HALF_UP, HALF_EVEN and HALF_DOWN. No precision is guaranteed for {@code exponent < 0} but the 557 * result is usually exact up to 10-20 ULP. 558 * <p> 559 * Properties of the X3.274-1996 algorithm are: 560 * <ul> 561 * <li>An {@code IllegalArgumentException} is thrown if {@code abs(n) > 999999999}</li> 562 * <li>if {@code exponent} is zero, one is returned even if {@code uDecimalBase} is zero, otherwise 563 * <ul> 564 * <li>if {@code exponent} is positive, the result is calculated via the repeated squaring technique into a single 565 * accumulator</li> 566 * <li>if {@code exponent} is negative, the result is calculated as if {@code exponent} were positive; this value is then divided 567 * into one</li> 568 * <li>The final value from either the positive or negative case is then rounded using this arithmetic's 569 * {@link #getRoundingMode() rounding mode}</li> 570 * </ul> 571 * </li> 572 * </ul> 573 * <p> 574 * Note: this operation is <b>not</b> strictly garbage free since internally, two {@link ThreadLocal} objects are 575 * used to calculate the result. The {@code ThreadLocal} values may become garbage if the thread becomes garbage. 576 * 577 * @param uDecimalBase 578 * the unscaled decimal base value 579 * @param exponent 580 * exponent to which {@code uDecimalBase} is to be raised. 581 * @return <tt>uDecimalBase<sup>exponent</sup></tt> 582 * @throws IllegalArgumentException 583 * if {@code abs(exponent) > 999999999} 584 * @throws ArithmeticException 585 * if {@code uDecimalBase==0} and {@code exponent} is negative. (This would cause a division by zero.), 586 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 587 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 588 */ 589 long pow(long uDecimalBase, int exponent); 590 591 /** 592 * Returns an unscaled decimal whose value is {@code (uDecimal << n)}. The shift distance, {@code n}, may be 593 * negative, in which case this method performs a right shift. The result is equal to 594 * <tt>round(uDecimal * 2<sup>n</sup>)</tt> using this arithmetic's {@link #getRoundingMode() rounding mode} if 595 * rounding is necessary. 596 * 597 * @param uDecimal 598 * the unscaled decimal value to shift 599 * @param n 600 * shift distance, in bits. 601 * @return {@code round(uDecimal << n)} 602 * @throws ArithmeticException 603 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 604 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 605 * @see #shiftRight(long, int) 606 */ 607 long shiftLeft(long uDecimal, int n); 608 609 /** 610 * Returns an unscaled decimal whose value is {@code (uDecimal >> n)}. The shift distance, {@code n}, may be 611 * negative, in which case this method performs a left shift. The result is equal to 612 * <tt>round(uDecimal / 2<sup>n</sup>)</tt> using this arithmetic's {@link #getRoundingMode() rounding mode} if 613 * rounding is necessary. 614 * 615 * @param uDecimal 616 * the unscaled decimal value to shift 617 * @param n 618 * shift distance, in bits. 619 * @return {@code round(uDecimal >> n)} 620 * @throws ArithmeticException 621 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 622 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 623 * @see #shiftLeft(long, int) 624 */ 625 long shiftRight(long uDecimal, int n); 626 627 /** 628 * Returns an unscaled decimal whose value is rounded to the specified {@code precision} using the 629 * {@link #getRoundingMode() rounding mode} of this arithmetic. 630 * <p> 631 * Note that this method does not change the scale of the value --- extra digits are simply zeroised. 632 * <p> 633 * <i>Examples and special cases:</i> 634 * <ul> 635 * <li><b>precision = 0</b><br> 636 * value is rounded to an integer value</li> 637 * <li><b>precision = 2</b><br> 638 * value is rounded to the second digit after the decimal point</li> 639 * <li><b>precision = -3</b><br> 640 * value is rounded to the thousands</li> 641 * <li><b>precision ≥ scale</b><br> 642 * values is returned unchanged</li> 643 * <li><b>precision < scale - 18</b><br> 644 * {@code IllegalArgumentException} is thrown</li> 645 * </ul> 646 * 647 * @param uDecimal 648 * the unscaled decimal value to round 649 * @param precision 650 * the precision to use for the rounding, for instance 2 to round to the second digit after the decimal 651 * point; must be at least {@code (scale - 18)} 652 * @return an unsigned decimal rounded to the given precision 653 * @throws IllegalArgumentException 654 * if {@code precision < scale - 18} 655 * @throws ArithmeticException 656 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary or if an 657 * overflow occurs and the {@link #getOverflowMode() overflow mode} is set to throw an exception 658 */ 659 long round(long uDecimal, int precision); 660 661 /** 662 * Converts the specified long value to an unscaled decimal. An exception is thrown if the specified value is too 663 * large to be represented as a Decimal of this arithmetic's {@link #getScale() scale}. 664 * 665 * @param value 666 * the value to convert 667 * @return the unscaled decimal representing the same value as the given long value 668 * @throws IllegalArgumentException 669 * if {@code value} is too large to be represented as a Decimal with the scale of this arithmetic 670 */ 671 long fromLong(long value); 672 673 /** 674 * Converts the specified float value to an unscaled decimal. An exception is thrown if the specified value is too 675 * large to be represented as a Decimal of this arithmetic's {@link #getScale() scale}. 676 * 677 * @param value 678 * the value to convert 679 * @return the unscaled decimal representing the same value as the given float value 680 * @throws IllegalArgumentException 681 * if {@code value} is NaN or infinite or if the magnitude is too large for the float to be represented 682 * as a {@code Decimal} with the scale of this arithmetic 683 * @throws ArithmeticException 684 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 685 */ 686 long fromFloat(float value); 687 688 /** 689 * Converts the specified double value to an unscaled decimal. An exception is thrown if the specified value is too 690 * large to be represented as a Decimal of this arithmetic's {@link #getScale() scale}. 691 * 692 * @param value 693 * the value to convert 694 * @return the unscaled decimal representing the same value as the given double value 695 * @throws IllegalArgumentException 696 * if {@code value} is NaN or infinite or if the magnitude is too large for the double to be represented 697 * as a {@code Decimal} with the scale of this arithmetic 698 * @throws ArithmeticException 699 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 700 */ 701 long fromDouble(double value); 702 703 /** 704 * Converts the specified {@link BigInteger} value to an unscaled decimal. An exception is thrown if the specified 705 * value is too large to be represented as a Decimal of this arithmetic's {@link #getScale() scale}. 706 * 707 * @param value 708 * the value to convert 709 * @return the unscaled decimal representing the same value as the given big integer value 710 * @throws IllegalArgumentException 711 * if {@code value} is too large to be represented as a Decimal with the scale of this arithmetic 712 */ 713 long fromBigInteger(BigInteger value); 714 715 /** 716 * Converts the specified {@link BigDecimal} value to an unscaled decimal. An exception is thrown if the specified 717 * value is too large to be represented as a Decimal of this arithmetic's {@link #getScale() scale}. 718 * <p> 719 * Note: this operation is <b>not</b> garbage free, meaning that new temporary objects may be allocated during the 720 * conversion. 721 * 722 * @param value 723 * the value to convert 724 * @return the unscaled decimal representing the same value as the given big decimal value 725 * @throws IllegalArgumentException 726 * if {@code value} is too large to be represented as a Decimal with the scale of this arithmetic 727 * @throws ArithmeticException 728 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 729 */ 730 long fromBigDecimal(BigDecimal value); 731 732 /** 733 * Converts the specified unscaled decimal with the given scale to another unscaled decimal of the scale of this 734 * arithmetic. 735 * 736 * @param unscaledValue 737 * the unscaled decimal value to convert 738 * @param scale 739 * the scale associated with {@code unscaledValue} 740 * @return the unscaled decimal representing the same value as the given unscaled decimal with the new scale defined 741 * by this arithmetic 742 * @throws IllegalArgumentException 743 * if the unscaled value with the specified scale is too large to be represented as a Decimal with the 744 * scale of this arithmetic 745 * @throws ArithmeticException 746 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 747 */ 748 long fromUnscaled(long unscaledValue, int scale); 749 750 /** 751 * Translates the string representation of a {@code Decimal} into an unscaled Decimal. The string representation 752 * consists of an optional sign, {@code '+'} or {@code '-'} , followed by a sequence of zero or more decimal digits 753 * ("the integer"), optionally followed by a fraction. 754 * <p> 755 * The fraction consists of a decimal point followed by zero or more decimal digits. The string must contain at 756 * least one digit in either the integer or the fraction. If the fraction contains more digits than this 757 * arithmetic's {@link #getScale() scale}, the value is rounded using the arithmetic's {@link #getRoundingMode() 758 * rounding mode}. An exception is thrown if the value is too large to be represented as a Decimal of this 759 * arithmetic's scale. 760 * 761 * @param value 762 * a {@code String} containing the decimal value representation to be parsed 763 * @return the decimal as unscaled {@code long} value 764 * @throws NumberFormatException 765 * if {@code value} does not represent a valid {@code Decimal} or if the value is too large to be 766 * represented as a Decimal with the scale of this arithmetic 767 * @throws ArithmeticException 768 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 769 */ 770 long parse(String value); 771 772 /** 773 * Translates the string representation of a {@code Decimal} into an unscaled Decimal. The string representation 774 * consists of an optional sign, {@code '+'} or {@code '-'} , followed by a sequence of zero or more decimal digits 775 * ("the integer"), optionally followed by a fraction. 776 * <p> 777 * The fraction consists of a decimal point followed by zero or more decimal digits. The string must contain at 778 * least one digit in either the integer or the fraction. If the fraction contains more digits than this 779 * arithmetic's {@link #getScale() scale}, the value is rounded using the arithmetic's {@link #getRoundingMode() 780 * rounding mode}. An exception is thrown if the value is too large to be represented as a Decimal of this 781 * arithmetic's scale. 782 * 783 * @param value 784 * a character sequence such as a {@code String} containing the decimal value representation to be parsed 785 * @param start 786 * the start index to read characters in {@code value}, inclusive 787 * @param end 788 * the end index where to stop reading in characters in {@code value}, exclusive 789 * @return the decimal as unscaled {@code long} value 790 * @throws IndexOutOfBoundsException 791 * if {@code start < 0} or {@code end > value.length()} 792 * @throws NumberFormatException 793 * if {@code value} does not represent a valid {@code Decimal} or if the value is too large to be 794 * represented as a Decimal with the scale of this arithmetic 795 * @throws ArithmeticException 796 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 797 */ 798 long parse(CharSequence value, int start, int end); 799 800 /** 801 * Converts the specified unscaled decimal value into a long value and returns it. The arithmetic's 802 * {@link #getRoundingMode() rounding mode} is applied if rounding is necessary. 803 * 804 * @param uDecimal 805 * the unscaled decimal value to convert into a long value 806 * @return the {@code uDecimal} value converted into a long value, possibly rounded or truncated 807 * @throws ArithmeticException 808 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 809 */ 810 long toLong(long uDecimal); 811 812 /** 813 * Converts the specified unscaled decimal value into an unscaled value of the given scale. The arithmetic's 814 * {@link #getRoundingMode() rounding mode} is applied if rounding is necessary. 815 * 816 * @param uDecimal 817 * the unscaled decimal value to convert into an unscaled value of the specified scale 818 * @param scale 819 * the target scale for the result value 820 * @return the {@code uDecimal} value converted into an unscaled value of the specified scale, possibly rounded or 821 * truncated 822 * @throws IllegalArgumentException 823 * if the unscaled value with this arithmetic's scale is too large to be represented as an unscaled 824 * decimal with the specified scale 825 * @throws ArithmeticException 826 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 827 */ 828 long toUnscaled(long uDecimal, int scale); 829 830 /** 831 * Converts the specified unscaled decimal value into a float value and returns it. The arithmetic's 832 * {@link #getRoundingMode() rounding mode} is applied if rounding is necessary. 833 * 834 * @param uDecimal 835 * the unscaled decimal value to convert into a float value 836 * @return the {@code uDecimal} value converted into a float value, possibly rounded or truncated 837 * @throws ArithmeticException 838 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 839 */ 840 float toFloat(long uDecimal); 841 842 /** 843 * Converts the specified unscaled decimal value into a double value and returns it. The arithmetic's 844 * {@link #getRoundingMode() rounding mode} is applied if rounding is necessary. 845 * 846 * @param uDecimal 847 * the unscaled decimal value to convert into a double value 848 * @return the {@code uDecimal} value converted into a double value, possibly rounded or truncated 849 * @throws ArithmeticException 850 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 851 */ 852 double toDouble(long uDecimal); 853 854 /** 855 * Converts the specified unscaled decimal value into a {@link BigDecimal} value using this arithmetic's 856 * {@link #getScale() scale} for the result value. 857 * <p> 858 * Note: this operation is <b>not</b> strictly garbage free since the result value is usually allocated; however no 859 * temporary objects other than the result are allocated during the conversion. 860 * 861 * @param uDecimal 862 * the unscaled decimal value to convert into a {@code BigDecimal} value 863 * @return the {@code uDecimal} value converted into a {@code BigDecimal} value 864 */ 865 BigDecimal toBigDecimal(long uDecimal); 866 867 /** 868 * Converts the specified unscaled decimal value into a {@link BigDecimal} value using the specified {@code scale} 869 * for the result value. The arithmetic's {@link #getRoundingMode() rounding mode} is applied if rounding is 870 * necessary. 871 * <p> 872 * Note: this operation is <b>not</b> garbage free since the result value is usually allocated and also temporary 873 * objects may be allocated during the conversion. Note however that temporary objects are only allocated if the 874 * unscaled value of the result exceeds the range of a long value. 875 * 876 * @param uDecimal 877 * the unscaled decimal value to convert into a {@code BigDecimal} value 878 * @param scale 879 * the scale to use for the resulting {@code BigDecimal} value 880 * @return the {@code uDecimal} value converted into a {@code BigDecimal} value, possibly rounded or truncated 881 * @throws ArithmeticException 882 * if {@link #getRoundingMode() rounding mode} is UNNECESSARY and rounding is necessary 883 */ 884 BigDecimal toBigDecimal(long uDecimal, int scale); 885 886 /** 887 * Converts the specified unscaled decimal value into a {@link String} and returns it. If the {@link #getScale() 888 * scale} is zero, the conversion is identical to {@link Long#toString(long)}. For all other scales a value with 889 * exactly {@code scale} fraction digits is returned even if some trailing fraction digits are zero. 890 * <p> 891 * Note: this operation is <b>not</b> strictly garbage free since the result value is allocated; however no 892 * temporary objects other than the result are allocated during the conversion (internally a {@link ThreadLocal} 893 * {@link StringBuilder} object is used to construct the string value, which may become garbage if the thread 894 * becomes garbage). 895 * 896 * @param uDecimal 897 * the unscaled decimal value to convert into a {@code String} 898 * @return the {@code uDecimal} value as into a {@code String} 899 */ 900 String toString(long uDecimal); 901 902 /** 903 * Converts the specified unscaled decimal value into a {@link String} and appends the string to the 904 * {@code appendable}. 905 * <p> 906 * If the {@link #getScale() scale} is zero, the conversion into a string is identical to 907 * {@link Long#toString(long)}. For all other scales a string value with exactly {@code scale} fraction digits is 908 * created even if some trailing fraction digits are zero. 909 * <p> 910 * Note: this operation is <b>not</b> strictly garbage free since internally, a {@link ThreadLocal} string builder 911 * is used to construct the string. The {@code ThreadLocal} value may become garbage if the thread becomes garbage. 912 * 913 * @param uDecimal 914 * the unscaled decimal value to convert into a {@code String} 915 * @param appendable 916 * the appendable to which the string representation of the unscaled decimal value is to be appended 917 * @throws IOException 918 * If an I/O error occurs when appending to {@code appendable} 919 */ 920 void toString(long uDecimal, Appendable appendable) throws IOException; 921}