Java BigDecimal Conversion, Division traps

Source: Internet
Author: User

Source Address: http://blog.csdn.net/niannian_315/article/details/24354251

Today in the use of BigDecimal "inexplicable" phenomenon, although know to avoid use, but did not study. Take this opportunity to check and share the details of your participation.

In Java, it is often possible to use double BigDecimal and division operations, but the following uses require special care.

Java code
  1. Package com.ccxe.number;
  2. Import Java.math.BigDecimal;
  3. Import Java.math.RoundingMode;
  4. Public class Test {
  5. public static void Main (string[] args) {
  6. //Print 0.899999999999999911182158029987476766109466552734375
  7. System.out.println (new BigDecimal (2.00). Subtract (new BigDecimal (Double
  8. . toString (1.10)));
  9. //Double transfer BigDecimal Recommended Practice
  10. System.out.println (New BigDecimal (double.tostring (2.00))
  11. . Subtract (new BigDecimal (1.10)));
  12. //Print 0.90
  13. System.out.println (new BigDecimal ("2.00"). Subtract (new BigDecimal (
  14. "1.10")));
  15. //abnormal java.lang.arithmeticexception:non-terminating decimal expansion;
  16. //System.out.println (New BigDecimal ("2.00")
  17. //. Divide (New BigDecimal ("1.10"));
  18. //Print 1.81818
  19. System.out.println (new BigDecimal ("2.00"). Divide (
  20. New BigDecimal ("1.10"), 5, Roundingmode.half_even));
  21. }
  22. }

Will explain this phenomenon.

Body:

The code example in the introduction indicates two questions:

1, line 11th: The result of execution, actually and 18 lines different;

2, line 22nd: Except endless, unexpectedly throws an exception.

And more importantly, these two issues are very subtle when coding. =

Let's look at question 1th first:

When I see that the subtraction result is very long, I immediately think that 1.10 in the binary expression, is not accurate expression. The answer is then found in the JDK API. The statement is as follows:

C code
  1. Public BigDecimal (double val)
  2. converts a double to BigDecimal, which is the exact decimal representation of a double binary floating-point value. return
  3. The scale of the BigDecimal is the smallest value that makes (10scalexval) an integer.
  4. Note:
  5. (1) The result of this construction method has some unpredictability. One might think that writing new BigDecimal (0.1) in Java
  6. The created BigDecimal is exactly equal to 0.1 (non-scale value 1 with a scale of 1), but it is actually equal to
  7. 0.1000000000000000055511151231257827021181583404541015625. That's because 0.1 doesn't exactly surface.
  8. is shown as double (or, for that case, it cannot be represented as any finite-length binary decimal). In this way, the incoming
  9. The value of the build method does not exactly equal 0.1 (although it is equal to the value on the surface).
  10. (2) On the other hand, the String construction method is fully predictable: writing new BigDecimal ("0.1") creates a
  11. BigDecimal, it just equals the expected 0.1. Therefore, in comparison, it is generally advisable to use the String construction method first.
  12. (3) When a double must be used as a source for BigDecimal, note that this construction method provides an accurate conversion;
  13. It does not provide the same results as the following: First use the double.tostring (Double) method, and then use the
  14. BigDecimal (String) constructs a method that converts a double to a String. To get the result, use the
  15. The static valueOf (double) method.
  16. Parameters:
  17. Val-the double value to convert to BigDecimal .
  18. Thrown:
  19. NumberFormatException-If Val is infinitely large or NaN.

Thus, it can be seen that the classic "10 binary can not be accurately expressed as 2" problem.

Then look at the second question:

From the exception information "non-terminating decimal expansion;" (non-terminating decimal expansion) can be guessed, and may not be accurately expressed by the quotient. Then check the JDK API to find the following statement:

C code
    1. Public BigDecimal Divide (BigDecimal divisor)
    2. Returns a BigDecimal with a value of (this/divisor) with a preferred scale of (This.scale ()
    3. -Divisor.scale ()); If the exact quotient value cannot be represented (because it has an infinite decimal extension),
    4. The ArithmeticException is thrown.
    5. Parameters:
    6. Divisor-the value to divide for this BigDecimal.
    7. Return:
    8. This/divisor
    9. Thrown:
    10. ArithmeticException-If the exact quotient value does not have an infinite decimal extension

The above is the version of JDK API 1.5, 1.6, more than one meaning, it is recommended to prioritize the following methods:

C code
    1. Public BigDecimal Divide (BigDecimal divisor,
    2. int scale, //Precision
    3. Roundingmode roundingmode) //Rounding mode

You can avoid the above reported anomalies.

Java BigDecimal Conversion, Division Trap (GO)

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.