8305343: BigDecimal.fractionOnly() erroneously returns true for large scale value
Reviewed-by: darcy
This commit is contained in:
parent
dd59471798
commit
7c650489d2
@ -3596,7 +3596,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
*/
|
||||
private boolean fractionOnly() {
|
||||
assert this.signum() != 0;
|
||||
return (this.precision() - this.scale) <= 0;
|
||||
return this.precision() <= this.scale;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3624,8 +3624,15 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
if (fractionOnly())
|
||||
throw new ArithmeticException("Rounding necessary");
|
||||
|
||||
// If more than 19 digits in integer part it cannot possibly fit
|
||||
if ((precision() - scale) > 19) // [OK for negative scale too]
|
||||
/*
|
||||
* If more than 19 digits in integer part it cannot possibly fit.
|
||||
* Ensure that arithmetic does not overflow, so instead of
|
||||
* precision() - scale > 19
|
||||
* prefer
|
||||
* precision() - 19 > scale
|
||||
* since precision() > 0, so the lhs cannot overflow.
|
||||
*/
|
||||
if (precision() - 19 > scale) // [OK for negative scale too]
|
||||
throw new java.lang.ArithmeticException("Overflow");
|
||||
|
||||
// round to an integer, with Exception if decimal part non-0
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6806261 8211936
|
||||
* @bug 6806261 8211936 8305343
|
||||
* @summary Tests of BigDecimal.longValueExact
|
||||
*/
|
||||
import java.math.*;
|
||||
@ -37,6 +37,7 @@ public class LongValueExactTests {
|
||||
|
||||
failures += longValueExactSuccessful();
|
||||
failures += longValueExactExceptional();
|
||||
failures += longValueExactExceptional8305343();
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Incurred " + failures +
|
||||
@ -117,4 +118,27 @@ public class LongValueExactTests {
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private static int longValueExactExceptional8305343() {
|
||||
int failures = 0;
|
||||
List<BigDecimal> exceptionalCases =
|
||||
List.of(new BigDecimal("1e" + (Integer.MAX_VALUE - 1)),
|
||||
new BigDecimal("1e" + (Integer.MAX_VALUE))
|
||||
);
|
||||
|
||||
for (BigDecimal bd : exceptionalCases) {
|
||||
try {
|
||||
bd.longValueExact();
|
||||
failures++;
|
||||
System.err.println("Unexpected non-exceptional longValueExact on " + bd);
|
||||
} catch (ArithmeticException e) {
|
||||
if (!e.getMessage().toLowerCase().contains("overflow")) {
|
||||
failures++;
|
||||
System.err.println("Unexpected non-exceptional longValueExact on " + bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user