Java BigDecimal Detailed

Source: Internet
Author: User

1. Introduction

In the book "Effactive Java", the main design goals for float and double types are for scientific calculations and engineering calculations. They perform binary floating-point operations, which are designed to provide more accurate, fast approximation calculations over a wide range of values. However, they do not provide completely accurate results, so they should not be used in situations where precise results are required. However, business computing often requires the results to be accurate, when the bigdecimal will come in handy.

2.BigDecimalBrief 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. Test the Code 3.1 constructor (the main test is the two common constructors with a double and a string of parameter types)

BigDecimal adouble =new BigDecimal (1.22);

System. out. println ("construct with a Double value:" + adouble);

BigDecimal astring = new BigDecimal ("1.22");

System. out. println ("construct with a String value:" + astring);

What do you think the output will be? If you do not think the first one will output 1.22, then congratulations to you correctly, the output is as follows:

Construct with a doublevalue:1.2199999999999999733546474089962430298328399658203125

Construct with a String value:1.22

Description of the JDK: 1 The result of a construction method with a parameter type of double is somewhat unpredictable. One might think that writing Newbigdecimal (0.1) in Java creates a bigdecimal that is exactly equal to 0.1 (non-scale value 1, with a scale of 1). But it's actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be accurately represented as a double (or, for that case, it cannot be represented as any finite-length binary decimal). This way, the value passed into the construction method does not exactly equal 0.1 (although it is on the surface equal to the value).

2. On the other hand, the String construction method is fully predictable: writing Newbigdecimal ("0.1") creates a BigDecimal, which is exactly equal to the expected 0.1. Therefore, in comparison, it is generally advisable to use the string construction method first .

3. When a 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 the Double.toString(double) method, and then use the BigDecimal(String) constructor method to The double is converted to String. To get the result, use the static valueOf(double) method.

3.2 Addition operation

BigDecimal a =new BigDecimal ("1.22");

System. out. println ("construct with a String value:" + a);

BigDecimal B =new BigDecimal ("2.22");

A.add (b);

System. out. println ("Aplus B is:" + a);

It is easy to assume that the output will be:

Construct with a stringvalue:1.22

A plus b is:3.44

But actually a plus B is:1.22

4. Source Code Analysis 4.1 valueOf (Doubleval) method

Public Static BigDecimal valueOf (double val) {

Reminder:a zero Double returns ' 0.0 ', so we cannotfastpath

To use the constant ZERO. This might is important enough to

Justify a factory approach, a cache, or a few private

Constants, later.

returnnew BigDecimal (Double. ToString(val));//See 3.1 for the 3rd JDK description

}

4.2 Add (BigDecimal augend) method

Public BigDecimal Add (BigDecimal augend) {

long xs =this. intcompact; Integer number representation of the BigDecimal, example a of the intcompact value of 122

long ys = augend.intcompact;//Ibid.

BigInteger FST = (this. intcompact! =inflated)? null :this. intval;//initializes the value of BigInteger, intval a property of BigInteger type for BigDecimal

BigInteger snd = (augend.intcompact! =inflated)? null : Augend.intval;

int Rscale =this. scale;//Number of decimal digits

long Sdiff = (long) The difference of rscale-augend.scale;//decimal place

if (Sdiff! = 0) {//number of decimal digits to be counted as result

if (Sdiff < 0) {

int raise =checkscale (-sdiff);

Rscale =augend.scale;

if (xs = =inflated | |

(xs = longmultiplypowerten(xs,raise)) = =inflated)

FST =bigmultiplypowerten (raise);

}Else {

int raise =augend.checkscale (Sdiff);

if (ys = =inflated | | (ys =Longmultiplypowerten(ys,raise)) = =inflated)

SND = Augend.bigmultiplypowerten (raise);

}

}

if (xs! =inflated && ys! =inflated) {

long sum = xs + ys;

if (((sum ^ xs) & (sum ^ ys))) >= 0L)//To determine whether there is overflow

return BigDecimal. valueOf (Sum,rscale)//Returns the BigDecimal instance obtained using BigDecimal's static factory method

}

if (FST = =null)

FST =biginteger. valueOf (xs); static Factory method for//biginteger

if (snd = =null)

SND =biginteger. valueOf (YS);

BigInteger sum =fst.add (SND);

return (Fst.signum = = snd.signum)? New BigDecimal (sum,inflated, Rscale, 0):

New BigDecimal (sum,compactvalfor(sum), Rscale, 0);//Returns the BigDecimal object obtained through other construction methods

}

The above is only the analysis of the addition source code, minus multiplication in fact, the final return is a new BigDecimal object, because BigInteger and BigDecimal are immutable (immutable), in every step of the operation, will produce a new object, So A.add (b); Although an addition operation is done, a does not save the value of the added operation, and the correct usage should be a=a.add (b);

5. Summary

(1) Commercial computing uses BigDecimal.

(2) Use a constructor with the parameter type string as much as possible.

(3) BigDecimal are immutable (immutable), each step of the operation, will produce a new object, so in doing subtraction operation, you must save the value of the operation.

(4) We tend to overlook some of the implementation details at the bottom of the JDK, resulting in errors that require more attention.

Java BigDecimal Detailed

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.