Mercurial > hg > openjdk > jdk8u > jdk
changeset 13479:83c656d64088
8211936: Better String parsing
Reviewed-by: aph
author | igerasim |
---|---|
date | Wed, 03 Apr 2019 02:07:42 +0100 |
parents | 20c8a9b1cc6e |
children | 52f3117d3120 |
files | src/share/classes/java/math/BigDecimal.java |
diffstat | 1 files changed, 39 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/math/BigDecimal.java Mon Apr 01 14:21:23 2019 +0200 +++ b/src/share/classes/java/math/BigDecimal.java Wed Apr 03 02:07:42 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, 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 @@ -3060,9 +3060,32 @@ * @return this {@code BigDecimal} converted to a {@code long}. */ public long longValue(){ - return (intCompact != INFLATED && scale == 0) ? - intCompact: - toBigInteger().longValue(); + if (intCompact != INFLATED && scale == 0) { + return intCompact; + } else { + // Fastpath zero and small values + if (this.signum() == 0 || fractionOnly() || + // Fastpath very large-scale values that will result + // in a truncated value of zero. If the scale is -64 + // or less, there are at least 64 powers of 10 in the + // value of the numerical result. Since 10 = 2*5, in + // that case there would also be 64 powers of 2 in the + // result, meaning all 64 bits of a long will be zero. + scale <= -64) { + return 0; + } else { + return toBigInteger().longValue(); + } + } + } + + /** + * Return true if a nonzero BigDecimal has an absolute value less + * than one; i.e. only has fraction digits. + */ + private boolean fractionOnly() { + assert this.signum() != 0; + return (this.precision() - this.scale) <= 0; } /** @@ -3080,15 +3103,20 @@ public long longValueExact() { if (intCompact != INFLATED && scale == 0) return intCompact; + + // Fastpath zero + if (this.signum() == 0) + return 0; + + // Fastpath numbers less than 1.0 (the latter can be very slow + // to round if very small) + 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] throw new java.lang.ArithmeticException("Overflow"); - // Fastpath zero and < 1.0 numbers (the latter can be very slow - // to round if very small) - if (this.signum() == 0) - return 0; - if ((this.precision() - this.scale) <= 0) - throw new ArithmeticException("Rounding necessary"); + // round to an integer, with Exception if decimal part non-0 BigDecimal num = this.setScale(0, ROUND_UNNECESSARY); if (num.precision() >= 19) // need to check carefully @@ -3130,7 +3158,7 @@ public int intValue() { return (intCompact != INFLATED && scale == 0) ? (int)intCompact : - toBigInteger().intValue(); + (int)longValue(); } /**