285 |
BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow (power)); |
BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow (power)); |
286 |
|
|
287 |
BigInteger parts[] = dividend.divideAndRemainder (valIntVal); |
BigInteger parts[] = dividend.divideAndRemainder (valIntVal); |
|
// System.out.println("int: " + parts[0]); |
|
|
// System.out.println("rem: " + parts[1]); |
|
288 |
|
|
289 |
BigInteger unrounded = parts[0]; |
BigInteger unrounded = parts[0]; |
290 |
if (parts[1].signum () == 0) // no remainder, no rounding necessary |
if (parts[1].signum () == 0) // no remainder, no rounding necessary |
293 |
if (roundingMode == ROUND_UNNECESSARY) |
if (roundingMode == ROUND_UNNECESSARY) |
294 |
throw new ArithmeticException ("newScale is not large enough"); |
throw new ArithmeticException ("newScale is not large enough"); |
295 |
|
|
296 |
int sign = unrounded.signum (); |
int sign = intVal.signum () * valIntVal.signum (); |
297 |
|
|
298 |
if (roundingMode == ROUND_CEILING) |
if (roundingMode == ROUND_CEILING) |
299 |
roundingMode = (sign == 1) ? ROUND_UP : ROUND_DOWN; |
roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN; |
300 |
else if (roundingMode == ROUND_FLOOR) |
else if (roundingMode == ROUND_FLOOR) |
301 |
roundingMode = (sign == 1) ? ROUND_DOWN : ROUND_UP; |
roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN; |
302 |
else |
else |
303 |
{ |
{ |
304 |
// half is -1 if remainder*2 < positive intValue (*power), 0 if equal, |
// half is -1 if remainder*2 < positive intValue (*power), 0 if equal, |
305 |
// 1 if >. This implies that the remainder to round is less than, |
// 1 if >. This implies that the remainder to round is less than, |
306 |
// equal to, or greater than half way to the next digit. |
// equal to, or greater than half way to the next digit. |
307 |
BigInteger posRemainder = sign == -1 ? parts[1].negate() : parts[1]; |
BigInteger posRemainder |
308 |
|
= parts[1].signum () < 0 ? parts[1].negate() : parts[1]; |
309 |
|
valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal; |
310 |
int half = posRemainder.shiftLeft(1).compareTo(valIntVal); |
int half = posRemainder.shiftLeft(1).compareTo(valIntVal); |
311 |
|
|
312 |
switch(roundingMode) |
switch(roundingMode) |
313 |
{ |
{ |
314 |
case ROUND_HALF_UP: |
case ROUND_HALF_UP: |
315 |
roundingMode = (half == -1) ? ROUND_DOWN : ROUND_UP; |
roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP; |
316 |
break; |
break; |
317 |
case ROUND_HALF_DOWN: |
case ROUND_HALF_DOWN: |
318 |
roundingMode = (half == 1) ? ROUND_UP : ROUND_DOWN; |
roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN; |
319 |
break; |
break; |
320 |
case ROUND_HALF_EVEN: |
case ROUND_HALF_EVEN: |
321 |
if (half == -1) |
if (half < 0) |
322 |
roundingMode = ROUND_DOWN; |
roundingMode = ROUND_DOWN; |
323 |
else if (half == 1) |
else if (half > 0) |
324 |
roundingMode = ROUND_UP; |
roundingMode = ROUND_UP; |
325 |
else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP |
else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP |
326 |
roundingMode = ROUND_UP; |
roundingMode = ROUND_UP; |
331 |
} |
} |
332 |
|
|
333 |
if (roundingMode == ROUND_UP) |
if (roundingMode == ROUND_UP) |
334 |
return new BigDecimal (unrounded.add (BigInteger.valueOf |
unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1)); |
|
(sign != 0 ? sign : 1)), newScale); |
|
335 |
|
|
336 |
// roundingMode == ROUND_DOWN |
// roundingMode == ROUND_DOWN |
337 |
return new BigDecimal (unrounded, newScale); |
return new BigDecimal (unrounded, newScale); |