< prev index next >

src/java.base/share/classes/java/math/BigDecimal.java

Print this page


   1 /*
   2  * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


3397 
3398     /**
3399      * Converts this {@code BigDecimal} to a {@code long}.
3400      * This conversion is analogous to the
3401      * <i>narrowing primitive conversion</i> from {@code double} to
3402      * {@code short} as defined in
3403      * <cite>The Java&trade; Language Specification</cite>:
3404      * any fractional part of this
3405      * {@code BigDecimal} will be discarded, and if the resulting
3406      * "{@code BigInteger}" is too big to fit in a
3407      * {@code long}, only the low-order 64 bits are returned.
3408      * Note that this conversion can lose information about the
3409      * overall magnitude and precision of this {@code BigDecimal} value as well
3410      * as return a result with the opposite sign.
3411      *
3412      * @return this {@code BigDecimal} converted to a {@code long}.
3413      * @jls 5.1.3 Narrowing Primitive Conversion
3414      */
3415     @Override
3416     public long longValue(){
3417         if (intCompact != INFLATED && scale == 0) {
3418             return intCompact;
3419         } else {
3420             // Fastpath zero and small values
3421             if (this.signum() == 0 || fractionOnly() ||
3422                 // Fastpath very large-scale values that will result
3423                 // in a truncated value of zero. If the scale is -64
3424                 // or less, there are at least 64 powers of 10 in the
3425                 // value of the numerical result. Since 10 = 2*5, in
3426                 // that case there would also be 64 powers of 2 in the
3427                 // result, meaning all 64 bits of a long will be zero.
3428                 scale <= -64) {
3429                 return 0;
3430             } else {
3431                 return toBigInteger().longValue();
3432             }
3433         }
3434     }
3435 
3436     /**
3437      * Return true if a nonzero BigDecimal has an absolute value less
3438      * than one; i.e. only has fraction digits.
3439      */
3440     private boolean fractionOnly() {
3441         assert this.signum() != 0;
3442         return (this.precision() - this.scale) <= 0;
3443     }
3444 
3445     /**
3446      * Converts this {@code BigDecimal} to a {@code long}, checking
3447      * for lost information.  If this {@code BigDecimal} has a
3448      * nonzero fractional part or is out of the possible range for a
3449      * {@code long} result then an {@code ArithmeticException} is
3450      * thrown.
3451      *
3452      * @return this {@code BigDecimal} converted to a {@code long}.
3453      * @throws ArithmeticException if {@code this} has a nonzero
3454      *         fractional part, or will not fit in a {@code long}.
3455      * @since  1.5
3456      */
3457     public long longValueExact() {
3458         if (intCompact != INFLATED && scale == 0)
3459             return intCompact;
3460 
3461         // Fastpath zero
3462         if (this.signum() == 0)
3463             return 0;
3464 
3465         // Fastpath numbers less than 1.0 (the latter can be very slow
3466         // to round if very small)
3467         if (fractionOnly())
3468             throw new ArithmeticException("Rounding necessary");
3469 
3470         // If more than 19 digits in integer part it cannot possibly fit
3471         if ((precision() - scale) > 19) // [OK for negative scale too]
3472             throw new java.lang.ArithmeticException("Overflow");
3473 





3474         // round to an integer, with Exception if decimal part non-0
3475         BigDecimal num = this.setScale(0, ROUND_UNNECESSARY);
3476         if (num.precision() >= 19) // need to check carefully
3477             LongOverflow.check(num);
3478         return num.inflated().longValue();
3479     }
3480 
3481     private static class LongOverflow {
3482         /** BigInteger equal to Long.MIN_VALUE. */
3483         private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
3484 
3485         /** BigInteger equal to Long.MAX_VALUE. */
3486         private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
3487 
3488         public static void check(BigDecimal num) {
3489             BigInteger intVal = num.inflated();
3490             if (intVal.compareTo(LONGMIN) < 0 ||
3491                 intVal.compareTo(LONGMAX) > 0)
3492                 throw new java.lang.ArithmeticException("Overflow");
3493         }


3497      * Converts this {@code BigDecimal} to an {@code int}.
3498      * This conversion is analogous to the
3499      * <i>narrowing primitive conversion</i> from {@code double} to
3500      * {@code short} as defined in
3501      * <cite>The Java&trade; Language Specification</cite>:
3502      * any fractional part of this
3503      * {@code BigDecimal} will be discarded, and if the resulting
3504      * "{@code BigInteger}" is too big to fit in an
3505      * {@code int}, only the low-order 32 bits are returned.
3506      * Note that this conversion can lose information about the
3507      * overall magnitude and precision of this {@code BigDecimal}
3508      * value as well as return a result with the opposite sign.
3509      *
3510      * @return this {@code BigDecimal} converted to an {@code int}.
3511      * @jls 5.1.3 Narrowing Primitive Conversion
3512      */
3513     @Override
3514     public int intValue() {
3515         return  (intCompact != INFLATED && scale == 0) ?
3516             (int)intCompact :
3517             (int)longValue();
3518     }
3519 
3520     /**
3521      * Converts this {@code BigDecimal} to an {@code int}, checking
3522      * for lost information.  If this {@code BigDecimal} has a
3523      * nonzero fractional part or is out of the possible range for an
3524      * {@code int} result then an {@code ArithmeticException} is
3525      * thrown.
3526      *
3527      * @return this {@code BigDecimal} converted to an {@code int}.
3528      * @throws ArithmeticException if {@code this} has a nonzero
3529      *         fractional part, or will not fit in an {@code int}.
3530      * @since  1.5
3531      */
3532     public int intValueExact() {
3533        long num;
3534        num = this.longValueExact();     // will check decimal part
3535        if ((int)num != num)
3536            throw new java.lang.ArithmeticException("Overflow");
3537        return (int)num;


   1 /*
   2  * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


3397 
3398     /**
3399      * Converts this {@code BigDecimal} to a {@code long}.
3400      * This conversion is analogous to the
3401      * <i>narrowing primitive conversion</i> from {@code double} to
3402      * {@code short} as defined in
3403      * <cite>The Java&trade; Language Specification</cite>:
3404      * any fractional part of this
3405      * {@code BigDecimal} will be discarded, and if the resulting
3406      * "{@code BigInteger}" is too big to fit in a
3407      * {@code long}, only the low-order 64 bits are returned.
3408      * Note that this conversion can lose information about the
3409      * overall magnitude and precision of this {@code BigDecimal} value as well
3410      * as return a result with the opposite sign.
3411      *
3412      * @return this {@code BigDecimal} converted to a {@code long}.
3413      * @jls 5.1.3 Narrowing Primitive Conversion
3414      */
3415     @Override
3416     public long longValue(){
3417         return (intCompact != INFLATED && scale == 0) ?
3418             intCompact:
3419             toBigInteger().longValue();























3420     }
3421 
3422     /**
3423      * Converts this {@code BigDecimal} to a {@code long}, checking
3424      * for lost information.  If this {@code BigDecimal} has a
3425      * nonzero fractional part or is out of the possible range for a
3426      * {@code long} result then an {@code ArithmeticException} is
3427      * thrown.
3428      *
3429      * @return this {@code BigDecimal} converted to a {@code long}.
3430      * @throws ArithmeticException if {@code this} has a nonzero
3431      *         fractional part, or will not fit in a {@code long}.
3432      * @since  1.5
3433      */
3434     public long longValueExact() {
3435         if (intCompact != INFLATED && scale == 0)
3436             return intCompact;










3437         // If more than 19 digits in integer part it cannot possibly fit
3438         if ((precision() - scale) > 19) // [OK for negative scale too]
3439             throw new java.lang.ArithmeticException("Overflow");
3440         // Fastpath zero and < 1.0 numbers (the latter can be very slow
3441         // to round if very small)
3442         if (this.signum() == 0)
3443             return 0;
3444         if ((this.precision() - this.scale) <= 0)
3445             throw new ArithmeticException("Rounding necessary");
3446         // round to an integer, with Exception if decimal part non-0
3447         BigDecimal num = this.setScale(0, ROUND_UNNECESSARY);
3448         if (num.precision() >= 19) // need to check carefully
3449             LongOverflow.check(num);
3450         return num.inflated().longValue();
3451     }
3452 
3453     private static class LongOverflow {
3454         /** BigInteger equal to Long.MIN_VALUE. */
3455         private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
3456 
3457         /** BigInteger equal to Long.MAX_VALUE. */
3458         private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
3459 
3460         public static void check(BigDecimal num) {
3461             BigInteger intVal = num.inflated();
3462             if (intVal.compareTo(LONGMIN) < 0 ||
3463                 intVal.compareTo(LONGMAX) > 0)
3464                 throw new java.lang.ArithmeticException("Overflow");
3465         }


3469      * Converts this {@code BigDecimal} to an {@code int}.
3470      * This conversion is analogous to the
3471      * <i>narrowing primitive conversion</i> from {@code double} to
3472      * {@code short} as defined in
3473      * <cite>The Java&trade; Language Specification</cite>:
3474      * any fractional part of this
3475      * {@code BigDecimal} will be discarded, and if the resulting
3476      * "{@code BigInteger}" is too big to fit in an
3477      * {@code int}, only the low-order 32 bits are returned.
3478      * Note that this conversion can lose information about the
3479      * overall magnitude and precision of this {@code BigDecimal}
3480      * value as well as return a result with the opposite sign.
3481      *
3482      * @return this {@code BigDecimal} converted to an {@code int}.
3483      * @jls 5.1.3 Narrowing Primitive Conversion
3484      */
3485     @Override
3486     public int intValue() {
3487         return  (intCompact != INFLATED && scale == 0) ?
3488             (int)intCompact :
3489             toBigInteger().intValue();
3490     }
3491 
3492     /**
3493      * Converts this {@code BigDecimal} to an {@code int}, checking
3494      * for lost information.  If this {@code BigDecimal} has a
3495      * nonzero fractional part or is out of the possible range for an
3496      * {@code int} result then an {@code ArithmeticException} is
3497      * thrown.
3498      *
3499      * @return this {@code BigDecimal} converted to an {@code int}.
3500      * @throws ArithmeticException if {@code this} has a nonzero
3501      *         fractional part, or will not fit in an {@code int}.
3502      * @since  1.5
3503      */
3504     public int intValueExact() {
3505        long num;
3506        num = this.longValueExact();     // will check decimal part
3507        if ((int)num != num)
3508            throw new java.lang.ArithmeticException("Overflow");
3509        return (int)num;


< prev index next >