The storage mechanism of floating-point numbers in memory is different from integer numbers. They have rounding errors and are used to represent any real number in computers. Specifically, this real number is obtained by multiplying an integer or fixed-point number (i.e., mantissa) by the power of an integer of a certain cardinality (usually 2 in a computer). This representation is similar to the scientific notation method with a cardinality of 10.
Therefore, floating-point numbers are usually accompanied by approximation or rounding due to inability to accurately represent. But the advantage of this design is that it can store a larger range of numbers over a fixed length.
1. There is a precision loss in the process of converting strings into float or double, but the accuracy loss of float and double is different.
std::string str="8.2";
float cc=atof(str.c_str()); // The value of cc is 8.1999998
std::string str="8.2";
double cc=atof(str.c_str()); // The value of cc is 8.1999999999999999999999999993
2. There may be accuracy loss in the process of converting float and double into characters, but it can be avoided through %.8lf.
(1)The float decimal point adds up to 6 effective digits. When the given float valid number is converted to characters within 6 bits, the accuracy will not be lost. When the valid number is greater than 6 bits, the accuracy will be lost.
//The accuracy is not lost
char buf[100]={'\0'};
float aa=8000.25;
sprintf(buf,"%f",aa); //8000.250000
//The accuracy is not lost
char buf[100]={'\0'};
float aa=8.00025;
sprintf(buf,"%f",aa); buf = 8.000250
//The accuracy is lost, there is an error
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%f",aa); //8000.250977
//The accuracy is lost, there is an error. When using .8lf is not effective, it is also invalid.
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%.8lf",aa); //8000.25097656
(2)The significant number added before and after the double decimal is only 16 bits. When the given double significant number is converted into a string within 16 bits, the accuracy will not be lost. When the significant number is greater than 16 bits, the accuracy will be lost.
There is an error
char buf[100]={'\0'};
double aa=121.437565871234012;
sprintf(buf,"%.20lf",aa); //121.43756587123401000000
//No error
char buf[100]={'\0'};
double aa=8000.256165;
sprintf(buf,"%.8lf",aa);
std::cout <<buf<<std::endl; //8000.25616500
3. Comparison of floating point numbers
Use "==" to compare the types that two doubles should be equal, and returning the true value is completely uncertain. The principle of computer calculation of floating-point numbers is to ensure that the necessary accuracy is correct.
When we judge that floating point numbers are equal, we recommend using range to determine them. If x is within a certain range, we think it is equal. As for how to define the range, it depends on the actual situation. float and double are different
So const float EPSINON = 0.00001;
If ((x >= - EPSINON) && (x <= EPSINON) This judgment is desirable
As for why you take 0.00001, you can define it according to the actual situation.
According to the above analysis, it is recommended to use the double type in the design-to-character conversion during system development, and the accuracy is set to %.8lf. When comparing floating point dozens, it is recommended to use EPSINON = 0.00000001
Therefore, floating-point numbers are usually accompanied by approximation or rounding due to inability to accurately represent. But the advantage of this design is that it can store a larger range of numbers over a fixed length.
1. There is a precision loss in the process of converting strings into float or double, but the accuracy loss of float and double is different.
std::string str="8.2";
float cc=atof(str.c_str()); // The value of cc is 8.1999998
std::string str="8.2";
double cc=atof(str.c_str()); // The value of cc is 8.1999999999999999999999999993
2. There may be accuracy loss in the process of converting float and double into characters, but it can be avoided through %.8lf.
(1)The float decimal point adds up to 6 effective digits. When the given float valid number is converted to characters within 6 bits, the accuracy will not be lost. When the valid number is greater than 6 bits, the accuracy will be lost.
//The accuracy is not lost
char buf[100]={'\0'};
float aa=8000.25;
sprintf(buf,"%f",aa); //8000.250000
//The accuracy is not lost
char buf[100]={'\0'};
float aa=8.00025;
sprintf(buf,"%f",aa); buf = 8.000250
//The accuracy is lost, there is an error
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%f",aa); //8000.250977
//The accuracy is lost, there is an error. When using .8lf is not effective, it is also invalid.
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%.8lf",aa); //8000.25097656
(2)The significant number added before and after the double decimal is only 16 bits. When the given double significant number is converted into a string within 16 bits, the accuracy will not be lost. When the significant number is greater than 16 bits, the accuracy will be lost.
There is an error
char buf[100]={'\0'};
double aa=121.437565871234012;
sprintf(buf,"%.20lf",aa); //121.43756587123401000000
//No error
char buf[100]={'\0'};
double aa=8000.256165;
sprintf(buf,"%.8lf",aa);
std::cout <<buf<<std::endl; //8000.25616500
3. Comparison of floating point numbers
Use "==" to compare the types that two doubles should be equal, and returning the true value is completely uncertain. The principle of computer calculation of floating-point numbers is to ensure that the necessary accuracy is correct.
When we judge that floating point numbers are equal, we recommend using range to determine them. If x is within a certain range, we think it is equal. As for how to define the range, it depends on the actual situation. float and double are different
So const float EPSINON = 0.00001;
If ((x >= - EPSINON) && (x <= EPSINON) This judgment is desirable
As for why you take 0.00001, you can define it according to the actual situation.
According to the above analysis, it is recommended to use the double type in the design-to-character conversion during system development, and the accuracy is set to %.8lf. When comparing floating point dozens, it is recommended to use EPSINON = 0.00000001