The use of BigDecimal in the financial industry in Java

Source: Internet
Author: User
Tags arithmetic operators

1. Introduction

In the Java language, double and float are used for binary floating-point calculations and do not get accurate results. The BigDecimal is used for accurate calculations. Scientific and engineering calculations of no more than 16 significant digits (preferably no more than 13 bits) can be used with double and float, but business operations that require accurate calculations or more than 16 significant digits (more than 13 are also recommended) need to be run using BigDecimal, such as the financial industry.

"The float and double types are particularly unsuitable for currency calculations because it is not possible to have a float or double to accurately identify 0.1 (or any other negative number of 10)," Effactive Java, 2nd edition of article 48th. "If you do not perform an operation, using string means that the amount is stronger than double and float, but the best is BigDecimal." The Financial industry HTTP communication interface can use a string to represent the amount, and if the internal interface is called, it is recommended to use BigDecimal.

2.BigDecimal Introduction

The BigDecimal consists of an integer non-scaling value of arbitrary precision and a 32-bit integer scale (scales ). If zero or positive, the scale is the number of digits after the decimal point. If it is negative, the non-scaling value of the number is multiplied by the 10 negative scale power. Therefore, the value represented by BigDecimal is (Unscaledvaluex10-scale).

3. Construction method of BigDecimal

In four categories, one is constructed from another BigDecimal object, a class is constructed using the Double/long/int/biginteger type, a class is constructed from string strings, and the last is constructed using the static method ValueOf (). The static method requires that the parameter is Double/long/int/biginteger and so on.

In the JDK API documentation, the public BigDecimal(double val) is interpreted as follows:

Will DoubleConverted to BigDecimal, the latter is double binary floating-point value accurate decimal representation。 Returned by BigDecimalThe scale is to make (10scalexval)is the minimum value for the integer.

Note:

    1. The result of this construction method is There is a certain unpredictability of . One might think that the BigDecimal created by writing new BigDecimal in Java is exactly equal to 0.1 (non-scale value 1, with a scale of 1), but it actually equals 0.100000000000000 0055511151231257827021181583404541015625. This is because 0.1 cannot be accurately represented as a double (or, for that case, it cannot be represented as a binary decimal of any finite length). In this way, the value of incoming to the construction method does not exactly equal 0.1 (although it is equal to the value on the surface).
    2. on the other hand, String construction method is fully predictable : Write new BigDecimal (" 0.1 ") A BigDecimal is created, which exactly equals the expected 0.1. Therefore, in comparison, it is generally advisable to use the String construction method first.
    3. when double must be used as a source for BigDecimal , be aware that this construction method provides an accurate conversion; it does not provide the same result as the following: First use double.tostring (Double) method, and then use the BigDecimal (String) Constructs a method, converting double to String . To get the result, use the static valueOf (double) method .

The explanation for public static BigDecimal valueOf(long Val) is as follows:

converts a long value to a BigDecimalwith a scale of 0. This "static Factory method" provided takes precedence over the (long) construction method, since the former allows the reuse of BigDecimal values that are often used .

Therefore, the use of the financial sector has the following conclusions:

1) The construction method of using string parameter is preferred;

2) If you need to construct bigdecimal by double, finite use of valueof (double val) method, so that the BigDecimal and string parameters are constructed with the same scale (that is, the scale is controllable);

3) The static factory method of ValueOf () takes precedence over the construction of type parameters such as long and int,

4) If you want to get the initialization value of the specified scale, such as 0 of 2 decimal places, you can use the following:

New BigDecimal ("0.00");

The method of constructing a string sets the scale according to the decimal place of the string, and the other construction methods require an additional call to Setscale () to set the scale.

4. BigDecimal scale, rounding method

The scale of the BigDecimal class is represented by the scales attribute, which is the number of decimal digits, and the precision is represented by the Precision property, which is the number of significant digits (that is, integer digits + decimal digits).

There are several rounding methods, and the BigDecimal class itself has a static member field that is rounded, but it is deprecated, and it is recommended to use the Roundingmode enumeration value.

The Roundingmode enumeration values are as follows:

Enumeration Constants Summary
CEILING
Rounding mode rounded to the positive infinity direction.
DOWN
Rounding mode rounded to the 0 direction.
FLOOR
Rounding mode rounded to the negative infinity direction.
HALF_DOWN
Rounding mode rounded to the nearest number direction, rounded down if the distance to the two adjacent digits is equal.
HALF_EVEN
Rounding mode rounded to the nearest number direction, rounded to adjacent even if the distance to the two adjacent numbers is equal.
HALF_UP
Rounding mode rounded to the nearest number direction, rounded up if the distance to the two adjacent digits is equal.
UNNECESSARY
The operation used to assert the request has a rounding pattern with precise results, so no rounding is required.
UP
Rounding mode is rounded away from the 0 direction.

One of the half_up is the most commonly used rounding, others are well understood according to the English name.

5.BigDecimal of Arithmetic

If you only access the value of the currency amount, you can use string, but if the amount is to participate in the arithmetic, you must use BigDecimal for the exact operation. BigDecimal compared with double, float, the bigdecimal operation is more accurate than double, float, but the speed is not double, float fast.

BigDecimal's arithmetic uses the following methods:

Public BigDecimal Add (BigDecimal value); Addition

Public BigDecimal Subtract (BigDecimal value); Subtraction

Public BigDecimal Multiply (BigDecimal value); Multiplication

Public BigDecimal Divide (BigDecimal value); Division

The scale of the arithmetic is explained in the JDK API as follows:

For all arithmetic operators, the operation is performed by first calculating the exact intermediate result, and then rounding it to the number of digits specified by the precision setting, if necessary, using the selected rounding mode . If the exact result is not returned, some digits of the exact result are discarded. When rounding increases the size of the returned result, the carry propagation of the leading number "9" may create a new digit. For example, rounding a value of 999.9 to a three-digit number equals 1000 on a value, represented as 100x101. In this case, the new "1" is the leading digit that returns the result.

In addition to the exact logical results, each arithmetic operation has a preferred scale to represent the result . The following table lists the preferred scales for each operation.

Preferred scale for arithmetic operations results
arithmetic preferred scale for results
Add Max (Addend.scale (), Augend.scale ())
Reducing Max (Minuend.scale (), Subtrahend.scale ())
By Multiplier.scale () + Multiplicand.scale ()
Except Dividend.scale ()-Divisor.scale ()

These scales are the scales used to return accurate arithmetic results , and the exact division may have to be used with the exception of larger scales, because accurate results may have more digits. For example,1/32 gets 0.03125.

The scale of the exact intermediate result of the logic before rounding is the preferred scale for the operation.

As can be seen above, if you call the above four methods, the scale of the computed result may be uncontrolled, BigDecimal also provides several overloaded methods for each operation, which can control the scale and rounding method of the result of the operation.

Take divide as an example to explain:

The JDK API explains the public BigDecimal divide(BigDecimal divisor) as follows:

Returns a BigDecimalwith a value of (This/divisor), with a preferred scale of (This.scale ()-Divisor.scale ()); if the exact quotient value cannot be represented (because it has an infinite decimal extension), the ArithmeticExceptionis thrown.
Parameters:
divisor-The value to divide for this BigDecimal .
Return:
This/divisor
Thrown:
ArithmeticException-If the exact quotient value does not have an infinite decimal extension
Start from the following versions:
1.5
As you can see, an exception is thrown when the quotient value cannot be accurately represented, and the division is large and may not accurately represent the quotient value. Therefore, you must specify the scale and rounding method. The following overloaded methods can be used by callers to specify the scale and rounding method.
Divide (BigDecimal divisor, int scale, Roundingmode roundingmode)
Divide (BigDecimal divisor, Roundingmode roundingmode)
Divide (BigDecimal divisor, Mathcontext MC)
These methods may also throw exceptions, but the exception is:divisor==0roundingmode==round_unnecessarythis.scale () Insufficient to accurately represent the result of the division. So as long as you set the scale and rounding method, you can basically ensure that the exception is not thrown.
6. Immutability of BigDecimal
The BigDecimal has a string-like feature, which is immutability. After calling Setscale or add, the scale and value of the original object will not change, so the return value of the method needs to be saved for use.
For example: A = A.setscale (2); A = A.add (b). Where A, B is the BigDecimal object.
7. Summary
1) The amount of financial industry must use BigDecimal to express;
2) BigDecimal It is best to use the construction method of string to create, if you want to use a double value as a parameter, you also use valueof to create the object.
3) When BigDecimal is arithmetic, it is best to specify its scale and rounding method, otherwise it may throw an exception.
4) BigDecimal is immutable; after arithmetic, use object to save the result;
5) Read the relevant API documentation, write test code to verify the transfer of relevant methods to better grasp.

Resources:
Java BigDecimal Detailed (http://blog.csdn.net/jackiehff/article/details/8582449)
"Effactive Java"
use BigDecimal for precise operation (http://www.cnblogs.com/chenssy/archive/2012/09/09/2677279.html)

The use of BigDecimal in the financial industry in Java

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.