A float, double calculation error problem that developers in the finance and payment industry have to know

Source: Internet
Author: User
Tags ibm developerworks

In most industries the calculation of floating-point numbers is relatively small, but in finance, payment industry is more, and in these two industries a small mistake

Could be a huge loss to the company.


In the past, we had a problem with a double type, which resulted in a dozens of fewer results compared to the actual results.

Yuan money. Although the amount of small, but caused by products, technology attention. By looking at the relevant information, we finally know that it is because of the float, double in the value containing the decimal

Rounding in the calculation process produces an error.


Floating-point operations are rarely accurate in floating-point operations. While some numbers (such as 0.5) can be accurately represented as binary (base 2) decimals (because 0.5

equals 2-1), but some other numbers (such as 0.1) cannot be accurately expressed. Therefore, floating-point arithmetic can cause rounding errors, resulting in a close but not equal to your

The results that may be desired. For example: The following code runs the actual value of the result to 100958.34, not 100000. Everyone can run and try.

public static void Main (string[] args) {float F = 0.1f;float sum = 0;for (int i=0; i<1000000; i++) {    sum + = f;} SYSTEM.OUT.PRINTLN (sum);}
Similarly, the result of multiplying the. 1*26 is not equal to the result obtained by the. 1 itself plus 26 times. When you cast a floating-point number to an integer, the resulting rounding error even

More serious, because casting to an integer type discards the non-integral part, and even for those who "seem" to be given an integer value, there are also problems. For example

The following code:

public static void Main (string[] args) {Double d = 29.0 * 0.01; System.out.println (d); SYSTEM.OUT.PRINTLN ((int) (d * 100));}

Operation Result:

0.2928

See the results are not very different, so we recommend that you do not use float, double and other floating-point values to represent the exact value of some non-integer values (such as a few dollars and a few cents such

decimal) needs to be very precise. Floating-point numbers are not exact values, so using them can result in rounding errors. Therefore, using a floating-point number to try to represent an exact quantity such as the amount of money is not

A good idea. Using floating-point numbers for dollar and cents calculations can have disastrous consequences. Floating-point numbers are best used to represent values such as measured values, which from the outset

Not exactly.


So how are we going to solve this problem?


The JDK developer encountered this problem very early, and in JDK1.3 provided us with a new class of processing precision values Bigdecimal,bigdecimal is the standard

class, no special support is required in the compiler, it can represent decimals of arbitrary precision and evaluate them. Internally, you can use any range of values of any precision and a

Conversion factor to represent BigDecimal, the conversion factor represents the number of points left to move the decimal point, so as to get the value within the desired range BigDecimal gives us the addition, subtraction, multiplication and removal

Such arithmetic operations, because BigDecimal is a class, and the object is immutable, unlike the float, double is the basic variable, so the calculated result will be put into a new bigdec

iMAL objects, so using BigDecimal can be expensive and not suitable for large-scale mathematical calculations. It is designed to represent decimals precisely, so we can

Use it to represent the calculation of currency and amount.


BigDecimal usage:

BigDecimal Construction Method:


BigDeci Mal has a total of 4 constructor methods BigDecimal (int) Creates an object with the integer value specified by the parameter. BigDecimal (double) creates an object with the double value specified by the parameter. BigDecimal (long) creates an object with a long integer value specified by the parameter. BigDecimal (String) creates an object that has the numeric value specified by the parameter as a string. The 

BigDecimal operation does not support +-*/This type of operation has its own method of operation:

BigDeci Mal Add (BigDecimal augend) addition Operation BigDecimal Subtract (BigDecimal subtrahend) subtraction Operation BigDecimal Multiply (BigDecimal Multiplicand) multiplication Operation BigDecimal Divide (BigDecimal divisor) Division operation 


  Let's take a look at the first F An example of loat accuracy error, calculated with BigDecimal:

public static void Main (string[] args) {float F = 0.1f;float sum = 0;for (int i=0; i<1000000; i++) {    sum + = f;} System.out.println ("float sum=" +sum); BigDecimal B1 = new BigDecimal (double.tostring (0.01)); BigDecimal total = new BigDecimal (double.tostring (0)); for (int i=0; i<1000000; i++) {Total=total.add (B1);} System.out.println ("BigDecimal total=" +total);

Results:

Float Sum=100958.34bigdecimal total=10000.00
We can see from the results that the result of using float calculation is error, and the result of using BigDecimal is correct. Let's look again at the second double precision

Examples of errors, calculated using BigDecimal:

public static void Main (string[] args) {Double d = 29.0 * 0.01; System.out.println (d);/***double calculates **/system.out.println (d *);/***bigdecimal calculates **/bigdecimal B1 = new BigDecimal ( Double.tostring (d));  BigDecimal b2 = new BigDecimal (double.tostring (100)); System.out.println (B1.multiply (B2). Doublevalue ());}

Results:

0.2928.99999999999999629.0

We can see from the results that the result is error using double, and the result of using BigDecimal is correct


From the above two examples, it can be seen that bigdecimal can handle the problem of floating point calculation accuracy, but the performance is much lower than that of float and double, but in order to improve

The accuracy of the calculation, especially as the amount of processing, is recommended to use BigDecimal to calculate, to avoid loss.

Conclusion:

The closing point is a quote from the IBM Document library: "Using floats and decimals in Java programs is full of traps." Floating-point numbers and decimals do not "behave" like integers,

You cannot assume that floating-point computations must produce integer or exact results, although they do "should". It is best to reserve floating-point arithmetic as a numerical value that is not accurately calculated, such as

Measurement. If you need to represent a fixed-point number (for example, a few dollars and a few cents), use BigDecimal. "。


Note: Part of this article references the IBM developerworks China document library


A float, double calculation error problem that developers in the finance and payment industry have to know

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.