Why floating point imprecision? (Reprint)

Why floating point imprecision?

In fact, this statement itself is not accurate, relatively accurate that statement is: 10 hex decimal, our internal computer code written by farmers in the program can not be accurately expressed in binary decimal.

What is binary decimals? It is shaped like a digital 101.11, note that this is a binary digital 0 and 1 only.

101.11 equal to 1 * 2 + 0 * 2 ^ 2 ^ 2 ^ 1 + 0 + 1 * 1 * 1 * 2 -1 + 2 (-2) = 0 + 1 + 4 + 1/2 + 1/4 = 5.75

The following figure shows a binary representation of the decimal form.

Write pictures described here

Can be seen from the drawings, the binary fraction, the right of the decimal value is capable of expressing the 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 ... 1 / (2 ^ n)

Now the question is, the computer can use these two 1 / (2 ^ n) to the sum of the fractional decimal expression.

We try to express how decimal 0.2 bar.

= 0.01 = 0.25 1/4, too

0.001 = 1/8 = 0.125, is too small

0.0011 = 1/8 + 1/16 = 0.1875, the approximate 0.2

0.00111 = 1/8 + 1/16 + 1/32 = 0.21875, a big

0.001101 = 1/8 + 1/16 + 1/64 = .203125 or large

0.0011001 = 1/8 + 1/16 + 1/128 = 0.1953125 good result this

0.00110011 = 1/8 + 1/16 + 1 / + 1 128/256 = 0.19921875 
already approaching, so be it.

This is what I can not say the exact meaning of the expression of decimal decimal binary decimal.

Computer representation of floating-point numbers

That is how specific internal computer representation of it?

The computer can not provide unlimited space for the program to store binary fraction.

It requires a predetermined length, in Java, provides two ways: float and double, respectively 32-bit and 64-bit.

Such a float can look at the internal representation (for example to 0.09f): 
Float.floatToRawIntBits (0.09f)

You'll get: 1,035,489,772, which is 10 decimal, converted into binary, make up 32 is preceded by a few 0:

0 01111011 01110000101000111101100

You can see it is divided into three sections: 
the first section represents a symbol (S): 0 positive, a negative expression is actually more accurate (-1) ^ 0

Second is exponent (e): 01111011, corresponding to the decimal 123

Third segment is the mantissa (M)

You see mantissa and exponent, will understand that this is actually the so-called scientific notation: 
(-1) ^ S * M * 2 ^ E

For example 0.09f, it is: 
0101110000101000111101100 * (2 ^ 123) 
seems wrong, it is certainly far greater than 0.09f!

This is because the IEEE754 floating-point representation is followed, we have just the s (symbol) is right, but e (exponent) and M (the mantissa) need to change:

For the exponent E, a total of 8, which is a signed number, in particular in accordance with the IEEE754 standard, or 0 if it is not 255, it is necessary to subtract an offset value called for float 127

Therefore E = e - 127 = 123-127 = -4

For the mantissa M, if the exponent is not 0 or 255, he actually hides a a 1 (space-saving, fully squeeze every bit ah) left of the decimal. 
I.e. M = 1.01110000101000111101100

Now write that: 
1.01110000101000111101100 * 2 ^ -4 
= .000101110000101000111101100 
= 1/16 + 1/64 + 1/128 + 1/256 + .... 
= .0900000035762786865234375

You see this is the internal representation of 0.09, it is clear that he was larger than 0.09, is inaccurate!

64-bit double precision floating point double is also similar, but longer mantissa and exponent, a wider range can be expressed. 
Sign bit: an 
order code: 11 bit 
mantissa: 52

Write pictures described here

The above examples 0.09f fact is the so-called normalized floating-point numbers, as well as non-normalized floating-point number here will not start.

Use a float

Since the floating point representation of this "precision" or "similarity", calculation accuracy is less critical for okay, which require precise time of operation (e.g. banks) If we would do with the float or double be careful, you may not get the results you want.

Specific improved method recommended we look at "Effective Java" in Article 48 recommended "use BigDecimal precision arithmetic to do."

Transfer from

Why floating point imprecision 
may attention of the public micro-channel number: farmers turn over code

Guess you like

Origin www.cnblogs.com/zhangyanlong/p/11304849.html