mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8261366: Add discussion of IEEE 754 to BigDecimal
Reviewed-by: bpb
This commit is contained in:
parent
414ee95b8e
commit
14cfbda39e
3 changed files with 101 additions and 42 deletions
|
@ -35,14 +35,15 @@ import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable, arbitrary-precision signed decimal numbers. A
|
* Immutable, arbitrary-precision signed decimal numbers. A {@code
|
||||||
* {@code BigDecimal} consists of an arbitrary precision integer
|
* BigDecimal} consists of an arbitrary precision integer
|
||||||
* <i>unscaled value</i> and a 32-bit integer <i>scale</i>. If zero
|
* <i>{@linkplain unscaledValue() unscaled value}</i> and a 32-bit
|
||||||
* or positive, the scale is the number of digits to the right of the
|
* integer <i>{@linkplain scale() scale}</i>. If zero or positive,
|
||||||
* decimal point. If negative, the unscaled value of the number is
|
* the scale is the number of digits to the right of the decimal
|
||||||
* multiplied by ten to the power of the negation of the scale. The
|
* point. If negative, the unscaled value of the number is multiplied
|
||||||
* value of the number represented by the {@code BigDecimal} is
|
* by ten to the power of the negation of the scale. The value of the
|
||||||
* therefore <code>(unscaledValue × 10<sup>-scale</sup>)</code>.
|
* number represented by the {@code BigDecimal} is therefore
|
||||||
|
* <code>(unscaledValue × 10<sup>-scale</sup>)</code>.
|
||||||
*
|
*
|
||||||
* <p>The {@code BigDecimal} class provides operations for
|
* <p>The {@code BigDecimal} class provides operations for
|
||||||
* arithmetic, scale manipulation, rounding, comparison, hashing, and
|
* arithmetic, scale manipulation, rounding, comparison, hashing, and
|
||||||
|
@ -220,6 +221,64 @@ import java.util.Objects;
|
||||||
* Comparable}, {@link java.util.SortedMap} or {@link
|
* Comparable}, {@link java.util.SortedMap} or {@link
|
||||||
* java.util.SortedSet} for more information.
|
* java.util.SortedSet} for more information.
|
||||||
*
|
*
|
||||||
|
* <h2>Relation to IEEE 754 Decimal Arithmetic</h2>
|
||||||
|
*
|
||||||
|
* Starting with its 2008 revision, the <cite>IEEE 754 Standard for
|
||||||
|
* Floating-point Arithmetic</cite> has covered decimal formats and
|
||||||
|
* operations. While there are broad similarities in the decimal
|
||||||
|
* arithmetic defined by IEEE 754 and by this class, there are notable
|
||||||
|
* differences as well. The fundamental similarity shared by {@code
|
||||||
|
* BigDecimal} and IEEE 754 decimal arithmetic is the conceptual
|
||||||
|
* operation of computing the mathematical infinitely precise real
|
||||||
|
* number value of an operation and then mapping that real number to a
|
||||||
|
* representable decimal floating-point value under a <em>rounding
|
||||||
|
* policy</em>. The rounding policy is called a {@linkplain
|
||||||
|
* RoundingMode rounding mode} for {@code BigDecimal} and called a
|
||||||
|
* rounding-direction attribute in IEEE 754-2019. When the exact value
|
||||||
|
* is not representable, the rounding policy determines which of the
|
||||||
|
* two representable decimal values bracketing the exact value is
|
||||||
|
* selected as the computed result. The notion of a <em>preferred
|
||||||
|
* scale/preferred exponent</em> is also shared by both systems.
|
||||||
|
*
|
||||||
|
* <p>For differences, IEEE 754 includes several kinds of values not
|
||||||
|
* modeled by {@code BigDecimal} including negative zero, signed
|
||||||
|
* infinities, and NaN (not-a-number). IEEE 754 defines formats, which
|
||||||
|
* are parameterized by base (binary or decimal), number of digits of
|
||||||
|
* precision, and exponent range. A format determines the set of
|
||||||
|
* representable values. Most operations accept as input one or more
|
||||||
|
* values of a given format and produce a result in the same format.
|
||||||
|
* A {@code BigDecimal}'s {@linkplain scale() scale} is equivalent to
|
||||||
|
* negating an IEEE 754 value's exponent. {@code BigDecimal} values do
|
||||||
|
* not have a format in the same sense; all values have the same
|
||||||
|
* possible range of scale/exponent and the {@linkplain
|
||||||
|
* unscaledValue() unscaled value} has arbitrary precision. Instead,
|
||||||
|
* for the {@code BigDecimal} operations taking a {@code MathContext}
|
||||||
|
* parameter, if the {@code MathContext} has a nonzero precision, the
|
||||||
|
* set of possible representable values for the result is determined
|
||||||
|
* by the precision of the {@code MathContext} argument. For example
|
||||||
|
* in {@code BigDecimal}, if a nonzero three-digit number and a
|
||||||
|
* nonzero four-digit number are multiplied together in the context of
|
||||||
|
* a {@code MathContext} object having a precision of three, the
|
||||||
|
* result will have three digits (assuming no overflow or underflow,
|
||||||
|
* etc.).
|
||||||
|
*
|
||||||
|
* <p>The rounding policies implemented by {@code BigDecimal}
|
||||||
|
* operations indicated by {@linkplain RoundingMode rounding modes}
|
||||||
|
* are a proper superset of the IEEE 754 rounding-direction
|
||||||
|
* attributes.
|
||||||
|
|
||||||
|
* <p>{@code BigDecimal} arithmetic will most resemble IEEE 754
|
||||||
|
* decimal arithmetic if a {@code MathContext} corresponding to an
|
||||||
|
* IEEE 754 decimal format, such as {@linkplain MathContext#DECIMAL64
|
||||||
|
* decimal64} or {@linkplain MathContext#DECIMAL128 decimal128} is
|
||||||
|
* used to round all starting values and intermediate operations. The
|
||||||
|
* numerical values computed can differ if the exponent range of the
|
||||||
|
* IEEE 754 format being approximated is exceeded since a {@code
|
||||||
|
* MathContext} does not constrain the scale of {@code BigDecimal}
|
||||||
|
* results. Operations that would generate a NaN or exact infinity,
|
||||||
|
* such as dividing by zero, throw an {@code ArithmeticException} in
|
||||||
|
* {@code BigDecimal} arithmetic.
|
||||||
|
*
|
||||||
* @see BigInteger
|
* @see BigInteger
|
||||||
* @see MathContext
|
* @see MathContext
|
||||||
* @see RoundingMode
|
* @see RoundingMode
|
||||||
|
@ -1681,7 +1740,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||||
*
|
*
|
||||||
* @param divisor value by which this {@code BigDecimal} is to be divided.
|
* @param divisor value by which this {@code BigDecimal} is to be divided.
|
||||||
* @throws ArithmeticException if the exact quotient does not have a
|
* @throws ArithmeticException if the exact quotient does not have a
|
||||||
* terminating decimal expansion
|
* terminating decimal expansion, including dividing by zero
|
||||||
* @return {@code this / divisor}
|
* @return {@code this / divisor}
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
* @author Joseph D. Darcy
|
* @author Joseph D. Darcy
|
||||||
|
@ -1745,7 +1804,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||||
* @throws ArithmeticException if the result is inexact but the
|
* @throws ArithmeticException if the result is inexact but the
|
||||||
* rounding mode is {@code UNNECESSARY} or
|
* rounding mode is {@code UNNECESSARY} or
|
||||||
* {@code mc.precision == 0} and the quotient has a
|
* {@code mc.precision == 0} and the quotient has a
|
||||||
* non-terminating decimal expansion.
|
* non-terminating decimal expansion,including dividing by zero
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public BigDecimal divide(BigDecimal divisor, MathContext mc) {
|
public BigDecimal divide(BigDecimal divisor, MathContext mc) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -71,37 +71,37 @@ public final class MathContext implements Serializable {
|
||||||
/**
|
/**
|
||||||
* A {@code MathContext} object whose settings have the values
|
* A {@code MathContext} object whose settings have the values
|
||||||
* required for unlimited precision arithmetic.
|
* required for unlimited precision arithmetic.
|
||||||
* The values of the settings are:
|
* The values of the settings are: {@code precision=0 roundingMode=HALF_UP}
|
||||||
* <code>
|
|
||||||
* precision=0 roundingMode=HALF_UP
|
|
||||||
* </code>
|
|
||||||
*/
|
*/
|
||||||
public static final MathContext UNLIMITED =
|
public static final MathContext UNLIMITED =
|
||||||
new MathContext(0, RoundingMode.HALF_UP);
|
new MathContext(0, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code MathContext} object with a precision setting
|
* A {@code MathContext} object with a precision setting
|
||||||
* matching the IEEE 754R Decimal32 format, 7 digits, and a
|
* matching the precision of the IEEE 754-2019 decimal32 format, 7 digits, and a
|
||||||
* rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
|
* rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}.
|
||||||
* IEEE 754R default.
|
* Note the exponent range of decimal32 is <em>not</em> used for
|
||||||
|
* rounding.
|
||||||
*/
|
*/
|
||||||
public static final MathContext DECIMAL32 =
|
public static final MathContext DECIMAL32 =
|
||||||
new MathContext(7, RoundingMode.HALF_EVEN);
|
new MathContext(7, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code MathContext} object with a precision setting
|
* A {@code MathContext} object with a precision setting
|
||||||
* matching the IEEE 754R Decimal64 format, 16 digits, and a
|
* matching the precision of the IEEE 754-2019 decimal64 format, 16 digits, and a
|
||||||
* rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
|
* rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}.
|
||||||
* IEEE 754R default.
|
* Note the exponent range of decimal64 is <em>not</em> used for
|
||||||
|
* rounding.
|
||||||
*/
|
*/
|
||||||
public static final MathContext DECIMAL64 =
|
public static final MathContext DECIMAL64 =
|
||||||
new MathContext(16, RoundingMode.HALF_EVEN);
|
new MathContext(16, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code MathContext} object with a precision setting
|
* A {@code MathContext} object with a precision setting
|
||||||
* matching the IEEE 754R Decimal128 format, 34 digits, and a
|
* matching the precision of the IEEE 754-2019 decimal128 format, 34 digits, and a
|
||||||
* rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
|
* rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}.
|
||||||
* IEEE 754R default.
|
* Note the exponent range of decimal64 is <em>not</em> used for
|
||||||
|
* rounding.
|
||||||
*/
|
*/
|
||||||
public static final MathContext DECIMAL128 =
|
public static final MathContext DECIMAL128 =
|
||||||
new MathContext(34, RoundingMode.HALF_EVEN);
|
new MathContext(34, RoundingMode.HALF_EVEN);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -29,12 +29,12 @@
|
||||||
package java.math;
|
package java.math;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a <i>rounding behavior</i> for numerical operations
|
* Specifies a <i>rounding policy</i> for numerical operations capable
|
||||||
* capable of discarding precision. Each rounding mode indicates how
|
* of discarding precision. Each rounding mode indicates how the least
|
||||||
* the least significant returned digit of a rounded result is to be
|
* significant returned digit of a rounded result is to be calculated.
|
||||||
* calculated. If fewer digits are returned than the digits needed to
|
* If fewer digits are returned than the digits needed to represent
|
||||||
* represent the exact numerical result, the discarded digits will be
|
* the exact numerical result, the discarded digits will be referred
|
||||||
* referred to as the <i>discarded fraction</i> regardless the digits'
|
* to as the <i>discarded fraction</i> regardless the digits'
|
||||||
* contribution to the value of the number. In other words,
|
* contribution to the value of the number. In other words,
|
||||||
* considered as a numerical value, the discarded fraction could have
|
* considered as a numerical value, the discarded fraction could have
|
||||||
* an absolute value greater than one.
|
* an absolute value greater than one.
|
||||||
|
@ -89,7 +89,7 @@ package java.math;
|
||||||
*
|
*
|
||||||
* @apiNote
|
* @apiNote
|
||||||
* Five of the rounding modes declared in this class correspond to
|
* Five of the rounding modes declared in this class correspond to
|
||||||
* rounding direction attributes defined in the <cite>IEEE Standard
|
* rounding-direction attributes defined in the <cite>IEEE Standard
|
||||||
* for Floating-Point Arithmetic</cite>, IEEE 754-2019. Where present,
|
* for Floating-Point Arithmetic</cite>, IEEE 754-2019. Where present,
|
||||||
* this correspondence will be noted in the documentation of the
|
* this correspondence will be noted in the documentation of the
|
||||||
* particular constant.
|
* particular constant.
|
||||||
|
@ -137,7 +137,7 @@ public enum RoundingMode {
|
||||||
* Rounding mode to round towards zero. Never increments the digit
|
* Rounding mode to round towards zero. Never increments the digit
|
||||||
* prior to a discarded fraction (i.e., truncates). Note that this
|
* prior to a discarded fraction (i.e., truncates). Note that this
|
||||||
* rounding mode never increases the magnitude of the calculated value.
|
* rounding mode never increases the magnitude of the calculated value.
|
||||||
* This mode corresponds to the IEEE 754-2019 rounding
|
* This mode corresponds to the IEEE 754-2019 rounding-direction
|
||||||
* attribute roundTowardZero.
|
* attribute roundTowardZero.
|
||||||
*
|
*
|
||||||
*<p>Example:
|
*<p>Example:
|
||||||
|
@ -168,7 +168,7 @@ public enum RoundingMode {
|
||||||
* result is positive, behaves as for {@code RoundingMode.UP};
|
* result is positive, behaves as for {@code RoundingMode.UP};
|
||||||
* if negative, behaves as for {@code RoundingMode.DOWN}. Note
|
* if negative, behaves as for {@code RoundingMode.DOWN}. Note
|
||||||
* that this rounding mode never decreases the calculated value.
|
* that this rounding mode never decreases the calculated value.
|
||||||
* This mode corresponds to the IEEE 754-2019 rounding
|
* This mode corresponds to the IEEE 754-2019 rounding-direction
|
||||||
* attribute roundTowardPositive.
|
* attribute roundTowardPositive.
|
||||||
*
|
*
|
||||||
*<p>Example:
|
*<p>Example:
|
||||||
|
@ -199,7 +199,7 @@ public enum RoundingMode {
|
||||||
* result is positive, behave as for {@code RoundingMode.DOWN};
|
* result is positive, behave as for {@code RoundingMode.DOWN};
|
||||||
* if negative, behave as for {@code RoundingMode.UP}. Note that
|
* if negative, behave as for {@code RoundingMode.UP}. Note that
|
||||||
* this rounding mode never increases the calculated value.
|
* this rounding mode never increases the calculated value.
|
||||||
* This mode corresponds to the IEEE 754-2019 rounding
|
* This mode corresponds to the IEEE 754-2019 rounding-direction
|
||||||
* attribute roundTowardNegative.
|
* attribute roundTowardNegative.
|
||||||
*
|
*
|
||||||
*<p>Example:
|
*<p>Example:
|
||||||
|
@ -232,7 +232,7 @@ public enum RoundingMode {
|
||||||
* fraction is ≥ 0.5; otherwise, behaves as for
|
* fraction is ≥ 0.5; otherwise, behaves as for
|
||||||
* {@code RoundingMode.DOWN}. Note that this is the rounding
|
* {@code RoundingMode.DOWN}. Note that this is the rounding
|
||||||
* mode commonly taught at school.
|
* mode commonly taught at school.
|
||||||
* This mode corresponds to the IEEE 754-2019 rounding
|
* This mode corresponds to the IEEE 754-2019 rounding-direction
|
||||||
* attribute roundTiesToAway.
|
* attribute roundTiesToAway.
|
||||||
*
|
*
|
||||||
*<p>Example:
|
*<p>Example:
|
||||||
|
@ -301,7 +301,7 @@ public enum RoundingMode {
|
||||||
* chiefly used in the USA. This rounding mode is analogous to
|
* chiefly used in the USA. This rounding mode is analogous to
|
||||||
* the rounding policy used for {@code float} and {@code double}
|
* the rounding policy used for {@code float} and {@code double}
|
||||||
* arithmetic in Java.
|
* arithmetic in Java.
|
||||||
* This mode corresponds to the IEEE 754-2019 rounding
|
* This mode corresponds to the IEEE 754-2019 rounding-direction
|
||||||
* attribute roundTiesToEven.
|
* attribute roundTiesToEven.
|
||||||
*
|
*
|
||||||
*<p>Example:
|
*<p>Example:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue