The accuracy of floating-point numbers in Java "Go"

Source: Internet
Author: User

When you are calculating money, please watch!!! Don't regret the loss!!!

phenomena 1 :

public static void Main (string[] args) {

System. out. println (0.030*100);//Output 3.0

System. out. println (0.031*100);//Output 3.1

System. out. println (0.032*100);//Output 3.2

System. out. println (0.033*100);//Output 3.3000000000000003

System. out. println (0.034*100);//Output 3.4000000000000004

System. out. println (0.035*100);//Output 3.5000000000000004

System. out. println (0.036*100);//Output 3.5999999999999996

System. out. println (0.037*100);//Output 3.6999999999999997

System. out. println (0.038*100);//Output 3.8

System. out. println (0.039*100);//Output 3.9

}

phenomena 2 :

public static void Main (string[] args) {

BigDecimal B1 = new BigDecimal ("0.236");

BigDecimal b2 = new BigDecimal (0.236);

System. out. println (B1);//Output 0.236

System. out. println (B2);//Output 0.2359999999999999875655021241982467472553253173828125

}

Describe:

When we use some "special numbers" for the operation, or call BigDecimal in the new BigDecimal (double val) to construct, you will get unexpected results.

Reason:

In Java, floating-point types are based on the IEEE754 standard. IEEE754 defines both 32-bit and 64-bit double-precision floating-point binary decimal standards. It is inaccurate to use binary notation for floating-point numbers such as Double,float.

At the same time, BigDecimal's API declaration is proposed to be constructed using new BigDecimal (String val), and when constructed with the new BigDecimal (double val), you will get unexpected results (the results of This constructor can somewhat unpredictable).

workaround (Take 0.236*100 = 23.599999999999998 For example):

1. Convert by string combined with BigDecimal.

String val = "0.236";

Constructed using the new BigDecimal (String val)

BigDecimal a = new BigDecimal ("" +val);

BigDecimal B = new BigDecimal ("" +100);

The number of decimal places is consistent with the number of bits in the construction parameter

System. out. println (a.multiply (b));//Output 23.600

2, by shifting the combination of BigDecimal to convert

String val = "0.236";

Constructed using the new BigDecimal (String val)

BigDecimal a = new BigDecimal ("" +val);

Move right Two bits

A = A.movepointright (2);

System. out. println (a);//Output 23.6

3, using the method of preserving the decimal place to convert

double result = 0.236*100;

System. out. println (result);//Output 23.599999999999998

The calculation retains the result after the decimal point of four bits, and so on, 1 after a few zeros is reserved after the decimal number. Two decimal places reserved as follows

result = (double) (Math. Round(result*100)/100.0);

System. out. println (result);//Output 23.6

4, use DecimalFormat to determine the number of digits after the decimal point

double val = 0.236*100;

Two digits after the decimal point, if three bits are reserved for "#.000"

DecimalFormat df = new decimalformat ("#.00");

String str = Df.format (val);

System. out. println (Double. ValueOf(str));//Output 23.6

5 、-----Many ways, one can

Experience:

There are many ways to deal with such precision problems, as long as they are not calculated directly using floating-point numbers.

Additional:

IEEE 754 uses scientific notation to represent floating-point numbers with a decimal number of 2. 32-bit floating-point numbers use 1-bit notation for the number, 8-bit to represent the exponent, and 23 bits to denote the mantissa, which is the fraction of the decimal. An exponent that is a signed integer can have positive or negative points. The fractional part is represented by a binary (base 2) decimal number. For 64-bit double-precision floating-point numbers, a 1-bit symbol representing the number, a 11-bit exponent, and a 52-bit indicating the mantissa. The following two graphs indicate:

Float (32-bit):

1-bit, sign bit

Power (8-bit)

Mantissa (32-bit)

Double (64-bit):

1-bit, sign bit

Power (11-bit)

Mantissa (52-bit)

are divided into three parts:

(1) A separate sign bit s directly encodes the symbol S.

(2) The power exponent E of the K-bit, the shift code representation .

(3) n bits of the decimal, the original code is indicated .

The accuracy of floating-point numbers in Java "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.