What is the sum of 100 and 0.1 equal ?, 1000.1 Addition
I. Preface
In the cognitive process, you may think that the computer will not have a computing error, but in fact, there is still a situation where the correct value cannot be obtained after the program is run. Among them, the most classic is the decimal operation. (Be careful when doing finance !!!)
II. Introduction
In our world, there is no doubt that the sum of 100 million pieces is 10. However, when we use the following C Language Program for computation, the result is not 10 (the results may be different in different languages, here we mainly talk about C ).
The first is a piece of computing code:
#include <stdio.h>int main(void) { float sum; int i; sum = 0; for (i=0 ;i<100;i++) { sum += 0.1; } printf("%f\n",sum);}
The running result is as follows:
10.000002
The result of computer compilation, linking, and running is 10.000002. No program error. Now let's take a look at the specific reasons.
Iii. Reasons for incorrect computation results
Simply put, the correct value cannot be expressed, resulting in the calculated result being an approximate value. The following is a further analysis.
First, let's take a look at how to use binary numbers to represent Decimals in the computer world:
For example, convert the binary number of the decimal point 1011.0011 to the decimal number. (You only need to multiply the numeric values and bitwise weights, and then add the result of the multiplication)
That is, 1*2 ^ 3 + 0*2 ^ 2 + 1*2 ^ 1 + 1*2 ^ 0 + 0*2 ^ (-1) + 0*2 ^ (-2) + 1*2 ^ (-3) + 1*2 ^ (-4) = 11.1875.
After learning about the decimal-to-decimal method in binary representation, the cause of the computing error is easy to understand. The value range of the four digits after the decimal point in binary format is: 0.0000 ~ 0.1111. Therefore, the corresponding decimal result is as follows:
From the above table, we can see that the next digit of 0 is 0.625. Therefore, 0 ~ A numeric computer between 0.0625 cannot be expressed by the binary number of four digits after the decimal point. Therefore, we can see that 0.1 cannot be expressed in 4-bit binary numbers. Even if you increase the number of binary digits, you cannot get the result of 2 ^ (-x) = 0.1.
In fact, after decimal 0.1 is converted into binary, it becomes 0.0001100110011 ...... (1100 cycles. Just like 1/3 is a truth. Therefore, the sum of 100 values is not equal to 10, but an approximate value.
------------------------------------------- The above is the answer to the title reason ---------------------------------------------
4. What is a floating point number?
In fact, the 1011.0011 representation is completely a binary representation on paper, and cannot be used within the computer (the computer is only 0101001 internally ...... Without the "." concept ). In fact, the programming language provides double and float ). Double-precision floating-point numbers use 64-bit, single-precision floating-point numbers use 32-bit to represent all decimals.
Floating Point Number: refers to the decimal point expressed by symbol, tail number, base number, and index.
Where: ± indicates the symbol, m indicates the ending number, n indicates the base number, and e indicates the index. The actual data does not consider the base number. Therefore:
Where:
1. symbol part: 1 indicates negative, 0 indicates positive, or 0.
2. The ending part uses a regular expression that sets the value before the decimal point to 1.
3. Exponential: the EXCESS system is used.
First look at the ending part. For decimal 0.75. We have the following representation:
① 0.75 = 0.75*10 ^ 0
② 0.75 = 75*10 ^ (-2)
③ 0.75 = 0.075*10 ^ 1
In decimal format, the regular expression is: the first digit is 0, and the first digit is not 0. The same is true for binary. It uses a regular expression that sets the value before the decimal point to 1. That is, after the decimal number represented by the binary number is shifted to the left or right (logical shift) for several times, the first digit of the integer part is changed to 1, and the second digit is changed to 0. in addition, the first of the 1st bits is not saved in the actual data.
For example 1011.0011:
Shift to 0001.0110011, make sure that the decimal point is 23: 0001.01100110000000000000000, only after the decimal point is retained to complete the regular expression: 01100110000000000000000.
Let's look at the index. EXCESS system performance: sets the center value of the exponent part to 0, so that negative numbers do not need to be expressed using symbols. For example, if 8 is a single-precision floating point, 11111111 of the maximum value of 225 = 1/2 means 01111111 = 127 means 0. The double precision is similar.
Therefore, for the performance of single-precision floating-point numbers, the value range is: 00000000 ~ 11111111 is-127 ~ 128. Take the following example:
# Include <stdio. h> # include <string. h> int main (int argc, char * argv []) {float data; unsigned long buff; int I; char n [34]; // store 0.75 as a single-precision floating point number in data = (float) 0.75; memcpy (& buff, & data, 4); for (I = 33; i> = 0; I --) {if (I = 1 | I = 10) {n [I] = '-';} else {if (buff % 2 = 1) {n [I] = '1';} else {n [I] = '0 ';} buff/= 2 ;}} n [33] = '\ 0'; printf ("% s \ n", n );}
Running result:
0-01111110-10000000000000000000000
Among them, 01111110 is 126, and EXCESS is represented as-1.
The first digit before the decimal point is 1. Therefore, the ending number is 1.10000000000000000000000, or 1.5.
That is, + 1.5*2 ^ (-1) = 0.75.
5. How to avoid problems caused by errors in decimal Calculation
You can replace the decimal number with an integer for calculation. Then, it is narrowing down the corresponding multiples.
Note:
1. If you have any bugs or errors, you are welcome to give suggestions or comments at any time.