A detailed problem caused by the IsPrime Algorithm
0943 details caused by the IsPrime algorithm //***************************** ** /// Thursday, September 18, 2014, written in dormitory //: xia hualin // ********************************** not long time no blog updates, recently, I have had a lot of troubles. I have already been a Junior. I have really calmed down and read a book. What I want to talk about today is a detailed problem caused by the IsPrime algorithm. The details I am talking about here are what I think. If there is anything wrong, I hope to correct it! The implementation of a simple IsPrime algorithm is as follows: copy the Code 1 bool IsPrime (int n) 2 {3 int I; 4 5 if (n % 2 = 0) return false; 6 for (I = 3; I <= sqrt (n); I + = 2) 7 {8 if (n % I = 0) return false; 9} 10 return true; 11} there are some serious errors in copying the code. Obviously, when the parameters are 1 and 2, the function returns an incorrect answer. To solve this problem, check 1 and 2 separately. You can simply add the following at the beginning of the function: if (n <= 1) return false; if (n = 2) return true; there is also a performance problem. The IsPrime algorithm is designed to improve efficiency, but in reality, sometimes it takes longer than the old algorithm. This problem exists in the control row of the for Loop: for (I = 3; I <= sqrt (n); I + = 2) although modern computers can calculate the square root within a relatively short period of time, it takes longer to calculate the square root than to execute simple arithmetic operations. In the program, sqrt (n) must be calculated every time a loop is executed, and n is the constant amount in the entire loop, so we calculate sqrt (n) for each loop) this is not so cost-effective. To avoid calling the sqrt () function again and again, you can calculate sqrt (n) before the loop and store it into a variable, for example: double limit = sqrt (n); for (I = 3; I <= limit; I ++ = 2) This simple change will significantly improve the implementation efficiency of the IsPrime algorithm. This IsPrime algorithm also has a difficult problem to identify. It is difficult to find this logical error because it may not appear in your thousands of test examples, for some special test examples, this implementation may produce the correct results on some machines and the incorrect answers on another machine. To understand this problem, I think it is necessary to write another article on floating point numbers in computers. However, due to the length constraints, I will not elaborate on the principle of strictly equal floating point numbers, is a dangerous behavior. Suppose n is 49 and it is the square of 7. What will be returned when the computer calls the sqrt () function for 49? In a strictly mathematical field, this square root is 7, but the computer does not work in this field. It returns only a floating point number close to 7, and this number may be 6.9999999999999999999, although this number is close to 7, this difference is enough to affect the result of I <= limit. If I is 7 and limit is 6.999999999, the last cycle of the Loop will not be executed, the program will never check whether 7 can be divisible, and 7 is the only factor of 49, in this way, the program will incorrectly classify the 49 prime numbers. On the other hand, if sqrt (49) returns 7.0 or 7.0000000001, The IsPrime algorithm will get the correct answer. Therefore, the correctness of this implementation depends on how the hardware executes the floating point calculation, and making the correctness of an algorithm dependent on the characteristics of the computer running it is a serious error. This problem can be easily solved. If the square root of n is smaller than a certain boundary, we always tend to check one more possible divisor to avoid any harm if we test one more divisor, we only pay a very small price to ensure that the algorithms can be correctly executed on different hardware. Such a trade-off is quite cost-effective for us as long as we make simple modifications: double limit = sqrt (n) + 1; The IsPrime algorithm itself is very simple, but the details deserve our attention.