Floating-point numbers in Java---------BigDecimal and double (preliminary)

Source: Internet
Author: User

Why use bigdecimal?

borrowing the Effactive Javain this book,the main design goals forfloat 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.

BigDecimal Introduction

        bigdecimal integer non-scale value by arbitrary precision   and 32   ( Scale) composition. If zero or positive, the scale is the number of digits after the decimal point. If negative, the non-scale value of the number is multiplied by the 10 The negative scale power. Therefore, bigdecimal The value represented is x 10-scale)

Construction method

BigDecimal astring = new BigDecimal ("1.22");

BigDecimal adouble = new BigDecimal (1.22);

BigDecimal bdouble = bigdecimal.valueof (1.22);

System.out.println (astring);

System.out.println (adouble);

System.out.println (bdouble);

Result:

1.22

1.2199999999999999733546474089962430298328399658203125

1.22

SOURCE Analysis:

The bigdecimal.valueof (1.22) construction method is actually called the constructor method BigDecimal (String val);

The JDK is described in:

1, the parameter type isDoubleThe result of the construction method is somewhat unpredictable. Some may think that inJavawrite inNewbigdecimal (0.1)of the createdBigDecimalexactly equals0.1(non-scale value1, its scale is1), but it actually equals0.1000000000000000055511151231257827021181583404541015625. This is because0.1cannot be accurately expressed asDouble(or, for that case, it cannot be represented as any finite-length binary decimal). This way, the value passed into the constructor method does not exactly equal0.1(although it is equal to the value on the surface).

2, on the other hand, string Span style= "font-family: the song Body;" > The construction method is fully predictable: write to newbigdecimal ("0.1") bigdecimal , It is exactly equal to the expected string construction method.

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 double.tostring (Double) method, and then use the BigDecimal (String) constructs a method that will Double converted to String . To get the result, use the static valueOf (double) method.

The correct result is output through decimal when the data volume accuracy is not very large . ( three decimal places reserved )

BigDecimal astring = new BigDecimal ("1.22");

BigDecimal adouble = new BigDecimal (1.22);

BigDecimal avalue = bigdecimal.valueof (1.22);

System.out.println (New DecimalFormat ("0.000"). Format (astring));

System.out.println (New DecimalFormat ("0.000"). Format (adouble));

System.out.println (New DecimalFormat ("0.000"). Format (avalue));

Result:

1.220

1.220

1.220

cause Analysis: DecimalFormat made use of his own rules of redundancy.

Summarize

(1) Commercial Computing Use BigDecimal .

(2) try to use the parameter type as String 's constructor.

(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 be easy to ignore JDK some of the underlying implementation details lead to errors that require more attention.

Question one: BigDecimal's accuracy problem (a guy on StackOverflow asked a related question)

System.out.println (New BigDecimal (0.1). ToString ()); 0.1000000000000000055511151231257827021181583404541015625system.out.println (New BigDecimal ("0.1"). ToString ()) ; 0.1system.out.println (New BigDecimal (Double.tostring ( 0.1000000000000000055511151231257827021181583404541015625)). toString ());//0.1system.out.println (New BigDecimal ( Double.tostring (0.1)). ToString ()); 0.1

  

Analyze the problem with the above code (the contents of the comment represent the output of this statement)

The first line: In fact, since the binary cannot accurately represent decimal decimal 0.1, but after the compiler reads the string "0.1", it must be converted to a double value of 8 bytes, so The compiler can use only one nearest value instead of 0.1, or 0.1000000000000000055511151231257827021181583404541015625. Thus, at run time, the true value passed to the BigDecimal constructor is 0.1000000000000000055511151231257827021181583404541015625. Second line: BigDecimal can correctly convert the string into a truly accurate floating-point number. The third line: The problem is that Double.tostring uses a certain amount of precision to round the double and then output it. Yes. The double.tostring (0.1000000000000000055511151231257827021181583404541015625) output is actually "0.1", So the number of BigDecimal represented is also 0.1. Line four: Based on the previous analysis, the fact that this line of code is equivalent to the third line conclusion: 1. If you want BigDecimal to be able to accurately represent the value you want, be sure to use a string to represent the decimal and pass it to the BigDecimal constructor. 2. If you use double.tostring to convert a double into a string and then call BigDecimal (String), this is also not reliable, it does not necessarily work as you think. 3. If you are not very concerned about whether you are fully accurate and use BigDecimal (double), pay attention to the special case of the double itself, the specification of the double itself defines several specific double values (Infinite,-infinite,nan ), do not pass these values to BigDecimal, or you will throw an exception. question two: Is it not to throw away the fractional part by forcing the double into int?
int x= (int) 1023.99999999999999; x=1024 Why?

The reason is that the binary cannot accurately represent some decimal decimals, so the double value of 1023.99999999999999 after compilation becomes 1024.

So, forcing a double into int is really throwing away the fractional part, but the value you write in the code is not necessarily the true double value that the compiler generates. Verification Code:
Double d = 1023.99999999999999;int x = (int) d; System.out.println (New BigDecimal (d). toString ()); 1024system.out.println (Long.tohexstring (double.doubletorawlongbits (d))); 4090000000000000SYSTEM.OUT.PRINTLN (x); 1024

As mentioned above, BigDecimal can be accurately represented by a double, remember.

We can also print the binary form of D directly, according to IEEE 754, we can calculate the 0x4090000000000000= (1024).

Reference:

Http://www.cnblogs.com/mingforyou/p/3344489.html

Http://stackoverflow.com/questions/8073912/why-do-we-need-to-convert-the-double-into-a-string-before-we-can-convert-it-int

Http://www.cnblogs.com/linjiqin/p/3413894.html

Floating-point numbers in Java---------BigDecimal and double (preliminary)

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.