cover

Hello, everyone, I am Zhuang, a programmer in the Internet, today and share with you the development of floating point calculation encountered how to do?

Why 0.1+0.2! = 0.3?

Let’s start with a weird code

The encoding of floating point numbers

First of all, we need to know why 0.1+0.2 is not equal to 0.3 in the computer world, you can try it yourself, here involves the encoding method of floating point number, floating point number in the computer storage in accordance with IEEE 754 floating point counting standard, can be expressed asAdopting the encoding method of mantissa + order code, the symbol (S), order part (E) and mantissa part (M) can be determined to determine a floating point number.

  1. Sign part (S)

0-1 – negative

  1. Step part (E) (index part) :

For floating-point numbers, the range of exponents is -127 to 128. For floating-point numbers, the range of exponents is -1023 to 1024. For floating-point numbers, the range is -127 to 128

  1. Mantissa part (M) :

The precision of a floating point number is determined by the number of mantissa digits:

2^23=8388608, so the decimal precision is only 6 to 7 digits. For a double, the mantissa is 52 bits, which in decimal is 2^52 = 4503599627370496, so the decimal precision is only 15 to 16 bits

So floating-point numbers can lose precision when handed to the computer for storage. Remember that float is up to 6 or 7 bits, and double is up to 15 or 16 bits.

Floating point number converted from decimal to binary

For example, how to convert 0.875 to binary?

  1. To split a floating point number into integer and decimal parts with a decimal point

  2. For integer parts, use: mod by 2. If it is 0, no operation is required

  3. For the decimal part, multiply by 2 and take the whole method. The calculation process is as follows

  1. Merge result: integer part + decimal part

The final binary result is 0.111. Here are the binary representations of 0.1 and 0.2

0.1 binary 0.0001100110011001... (infinite loop) 0.2 binary 0.0011001100110011... (Infinite loop)Copy the code

At this point we know that the 0.1 we’re looking at is not really 0.1, and at the same time the calculation is infinite. It turned out that the computer could not accurately represent floating point numbers such as 0.1 and 0.2, and used numbers with rounding errors, which caused the accuracy of floating point numbers to be lost in decimal conversion.

BigDecimal is recommended

Since floating-point precision is lost, and it is often necessary to calculate to a few decimal places in real business, especially in payment products, we can use Java’s native BigDecimal type to define floating-point values using BigDecimal. Floating-point operations are followed by examples of BigDecimal’s use

/ / subtraction
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");

BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);

// Compare the sizes
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
System.out.println(a.compareTo(b));

// Save a few decimal places
BigDecimal m = new BigDecimal("1.255433");
BigDecimal n = m.setScale(3,BigDecimal.ROUND_HALF_DOWN);
System.out.println(n);

// Divide and take the remainder
BigDecimal n = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n.divideAndRemainder(m);
System.out.println(dr[0]); / / 102
System.out.println(dr[1]); / / 0.105
Copy the code

Considerations for using BigDecimal

Alibaba Java Development Manual

I’m Zhuang, wechat search: technology cat, get the first update, and we’ll see you next time