Floating-point (double&float) calculation problems in Java

Source: Internet
Author: User
Tags mul

In a project that has just been completed, the problem of double type calculation is not accurate. After searching the web, the problem is resolved. Experience sharing, heresum up.

Floating-point type float and double in Java are not capable of precise operation. The problem is sometimes very serious. For example, the direct calculation of a double type 1.4x1.5 sometimes results in 2.0999999999999996, but in fact, it should be 2.10. Moreover, similar situations are not limited to multiplication calculations.

Special currency types are available in some programming languages to handle this situation, but Java does not. So, in business computing we need to use:java.math.BigDecimal .

BigDecimal there are altogether 4 construction methods, of which there are two that do not belong to int, they are:

1, BigDecimal (double val)

Translates a double into a BigDecimal.

2, BigDecimal (String val)

Translates the String repre sentation of a BigDecimal into a BigDecimal.

The above API brief description is fairly clear, and usually, the one above is easier to use. However, the detailed description of the first construction method is:

Note:the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal (. 1) is exactly equal to. 1, but it's actually equal to. 1000000000000000055511151231 257827021181583404541015625. Because. 1 cannot be represented exactly as a double (or, for that matter, as a bi nary fraction of any finite length). Thus, the Long value that's being passed in to the constructor are not exactly equal to. 1, appearances nonwithstanding.

The (String) constructor, on the other hand, is perfectly predictable:new BigDecimal (". 1") are exactly equal to. 1, as one would expect. Therefore, it is generally recommended and that the (String) constructor being used in preference to this one.

Therefore, if you need to calculate accurately, you should not use string to construct BigDecimal.

First, the solution:

It is now possible to solve this problem, the principle is to use bigdecimal and must be constructed with string.

But imagine, if you want to do an addition operation, you need to convert two floating-point numbers to string, then construct into BigDecimal, call the Add method on one of them, pass in another as the parameter, and then transform the result of the operation (BigDecimal) into a floating-point number. Yes, it's too tedious.

The following tool class Arith can simplify this part of the operation. It provides the following static methods, including subtraction and rounding:

Public static double Add (Double v1,double v2)

Public static Double sub (double v1,double v2)

Public static Double Mul (Double v1,double v2)

Public static Double div (Double v1,double v2)

Public static Double div (double v1,double v2,int scale)

Public static double round (double v,int scale)

Source file Arith.java:

Import Java.math.BigDecimal;
Public classarith{
Default division Operation Precision
private static final int def_div_scale = 10;
This class cannot be instantiated
Private Arith () {

}
/**

* provides accurate addition operations.

* @param v1 Summand

* @param v2 Addend

* @return of two parameters and

*/

public static double Add (Double v1,double v2) {

BigDecimal B1 = new BigDecimal (double.tostring (v1));

BigDecimal b2 = new BigDecimal (double.tostring (v2));

Return B1.add (B2). Doublevalue ();

}

public static double sub (double v1,double v2) {

BigDecimal B1 = new BigDecimal (double.tostring (v1));

BigDecimal b2 = new BigDecimal (double.tostring (v2));

Return B1.subtract (B2). Doublevalue ();

}


Publicstatic Double Mul (Double v1,double v2) {

BigDecimal B1 = new BigDecimal (double.tostring (v1));

BigDecimal b2 = new BigDecimal (double.tostring (v2));

Return b1.multiply (B2). Doublevalue ();

}


Publicstatic Double div (Double v1,double v2) {

Return Div (V1,v2,def_div_scale);

}


/**

* Provide (relative) accurate division operations. When an exception occurs, the scale parameter refers to the

* Fixed precision, after which the numbers are rounded.
*/

Publicstatic Double div (double v1,double v2,int scale) {

if (scale<0) {

throw New IllegalArgumentException (

"The scale must is a positive integer or zero");

}

BigDecimal B1 = new BigDecimal (double.tostring (v1));

BigDecimal b2 = new BigDecimal (double.tostring (v2));

Returnb1.divide (B2,SCALE,BIGDECIMAL.ROUND_HALF_UP). Doublevalue ();

}

Publicstatic double round (double V,int scale) {

if (scale<0) {

throw New IllegalArgumentException (

"The scale must is a positive integer or zero");

}

BigDecimal B = New BigDecimal (double.tostring (v));

BigDecimal one = new BigDecimal ("1");

Returnb.divide (ONE,SCALE,BIGDECIMAL.ROUND_HALF_UP). Doublevalue ();

}

}

Floating-point (double&float) calculation problems in Java

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.