I don't think many of my friends will use the float type in mysql, especially when we use money, we may use double precision, we know that the float type of mysql is a single-precision floating point type, which may cause data errors accidentally.
I don't think many of my friends will use the float type in mysql, especially when we use money, we may use double precision, we know that the float type of mysql is a single-precision floating point type, which may cause data errors accidentally.
A single-precision floating point uses 4-byte (32bit) to represent a floating point.
A computer floating point number that adopts the IEEE754 standard is represented in binary format internally.
For example, 7.22 cannot be expressed in 32-bit binary.
So it is not accurate.
Summary of float data types in mysql
Float: when the data range is less than ± 131072 (65536 × 2), float data accuracy is correct, but data beyond this range is unstable, no related parameter settings are found. Suggestion: Change float to double or decimal. The difference between the two is that double is a floating point computation, and decimal is a fixed point computation to obtain more accurate data.
1. float Type
The float column type cannot be found by default. The precision must be specified,
For example, if num float, insert into table (num) values (0.12); select * from table where num = 0.12, empty set.
The Code is as follows: |
|
Num float (0.12), insert into table (num) values (0.12); select * from table where num = will find this record. Mysql> create table tt -> ( -> Num float (9, 3) -> ); Query OK, 0 rows affected (0.03 sec) Mysql> insert into tt (num) values (1234567.8 ); ERROR 1264 (22003): Out of range value for column 'num' at row 1
|
Note: The field is out of the range and cannot be inserted.
The Code is as follows: |
|
Mysql> insert into tt (num) values (123456.8 ); Query OK, 1 row affected (0.00 sec) Mysql> select * from tt; + ------------ + | Num | + ------------ + | 1, 123456.797 | + ------------ + 1 row in set (0.00 sec)
|
Note: If the number of decimal places is not enough, it is automatically filled. However, there is a problem that the approximate values above exist.
The Code is as follows: |
|
Mysql> insert into tt (num) values (123456.867 ); Query OK, 1 row affected (0.04 sec) Mysql> select * from tt; + ------------ + | Num | + ------------ + | 1, 123456.797 | | 1, 123456.797 | | 1, 123456.867 | + ------------ + 3 rows in set (0.00 sec) Mysql & gt; select * from tt where num = 123456.867; + ------------ + | Num | + ------------ + | 1, 123456.867 | + ------------ + 1 row in set (0.00 sec) Mysql> insert into tt (num) values (2.8 ); Query OK, 1 row affected (0.04 sec) Mysql> select * from tt; + ------------ + | Num | + ------------ + | 1, 123456.797 | | 1, 123456.797 | | 1, 123456.867 | | 1, 2.800 | + ------------ + 4 rows in set (0.00 sec) Mysql & gt; select * from tt where num = 2.8; + ------- + | Num | + ------- + | 1, 2.800 | + ------- + 1 row in set (0.00 sec) Mysql> insert into tt (num) values (2.888888 ); Query OK, 1 row affected (0.00 sec) Mysql> select * from tt; + ------------ + | Num | + ------------ + | 1, 123456.797 | | 1, 123456.797 | | 1, 123456.867 | | 1, 2.800 | | 1, 2.889 | + ------------ + 5 rows in set (0.00 sec)
|
Note: If the number of decimal places exceeds the upper limit, the approximate value is automatically obtained.
Bytes --------------------------------------------------------------------------------------
I. Concepts and errors of Floating Point Numbers
A floating point number is a method used to represent a real number. It uses the E (exponential) Power of M (tail number) * B (base number) to represent a real number, when the length is certain, it indicates that the data range is large. But there are also errors, which is a famous floating point number Accuracy Problem! Floating Point Numbers are implemented in multiple ways. Most of the implementations of floating point numbers in computers comply with the IEEE754 standard. IEEE754 sets two types of Single-precision floating point numbers and double-precision floating point numbers. Single-precision floating point numbers use 4-byte (32bit) to represent floating point numbers, the format is: 1-bit symbol bit 8-bit indicates the index 23-bit indicates the tail number double-precision floating point number 8-byte (64bit) indicates the real number, the format is: 1-bit symbol bit 11-bit indicates the index 52-bit indicates the tail number at the same time, the IEEE754 standard also regulates the ending number format: d. dddddd ..., there is only one decimal point on the left and cannot be zero. The computer is binary. Therefore, the decimal point on the left is always 1. Obviously, this 1 can be omitted to improve the accuracy of the ending number. It can be seen from the above that the ending number of a Single-precision floating point number is expressed in 24bit, And the ending number of a double-precision floating point number is expressed in 53bit, which is converted to decimal:
2 ^ 24-1 = 16777215; 2 ^ 53-1 = 9007199254740991
As can be seen from the above, IEEE754 Single-precision floating point's valid binary number is 24 bits, in decimal format, it is 8 bits; double-precision floating point's valid binary number is 53 bits, in decimal format, it is 16 bits. Obviously, if a real number has more than eight valid digits and is represented by a single-precision floating point number, it will produce an error! Similarly, if the valid number of a real number exceeds 16 bits, the double-precision floating point number will also produce an error! For the number 1310720000000000000000.66, the valid number is 24 BITs, which are expressed by Single-precision or double-precision floating-point numbers, but with different degrees:
Single-precision floating point number: 1310720040000000000000.00; double-precision floating point number: 1310720000000000000000.00
Obviously, the double precision is less than 0.66, and the single precision is less than 4 trillion!
The above shows the error caused by the length limit, but this is not all! A computer floating point number that adopts the IEEE754 standard is represented in binary internally. However, an error occurs when a decimal number is converted to a binary floating point number, the reason is that all numbers can be converted to binary numbers with a limited length. For the number 131072.32, the valid number is 8 bits. It can be accurately expressed with a single-precision floating point number. Why is there a deviation? Let's take a look at the binary ending number of this data. We can see that the number is 10000000000000000001010001 ...... apparently, the number of tails exceeds 24 bits. According to the Rounding Rule, the number of tails is only 100000000000000000010100, resulting in a "strange" Phenomenon in the test! 131072.68 is represented as 131072.69 with a single-precision floating point number, for a similar reason. In fact, the number of valid digits is smaller than 8 digits, and the floating point number cannot be accurately expressed. The tail number of The number 7.22 cannot be expressed in the 24bit binary format, of course, there will be no problem in testing in the database (or 7.22 after rounding), but if you participate in some calculations, after the error accumulation, there may be a large deviation.
Ii. numeric types in mysql and oracle
Is it true that only mysql exists? Obviously not. As long as the implementation of floating point numbers conforms to the IEEE754 standard, there are the same problems.
Mysql numeric type (excluding Integer type ):
IEEE754 floating point: float (single precision), double or real (double Precision)
Number of points: decimal or numeric
Data Types in oracle:
Oracle floating point number: number (do not specify the precision)
IEEE754 floating point: BINARY_FLOAT (single precision), BINARY_DOUBLE (Double Precision) FLOAT, FLOAT (n) (ansi-required data type)
Number of points: number (p, s)
If you use BINARY_FLOAT in oracle for testing, the results are the same. Therefore, for data that involves currency or other precision-sensitive data, you should use a specific number of points for storage. For mysql, It is decimal, and for oracle, It is number (p, s ). Double-precision floating point number, which is also a problem for relatively large data!
Iii. floating point problems also exist in programming
Not only does the database have floating point numbers, but programming also exists, and even deserves more attention!
Through the above introduction, the error of floating point numbers should be clear. If complicated floating point calculation is performed in the program, the error will be further amplified. Therefore, if floating point numbers are used in programming, you must be aware of possible errors. Not only that, if the floating point is not properly processed, it will also lead to a program BUG! See the following statement: if (x! = Y) {z = 1/(x-y);} This statement seems no problem, but if it is a floating point number, it may be a problem! Then, let's see what the following statement will output: public class Test {public static void main (String [] args) throws Exception {System. out. print ("7.22-7.0 =" + (7.22f-7.0f);} we may assume that the output result is 0.22, but the actual result is 0.21999979!
Therefore, do not compare floating point numbers as much as possible in programming. Otherwise, some potential problems may occur! In addition, pay attention to some special floating point values, such as NaN, + 0,-0, + infinity, and-infinity. Although IEEE754 has made some conventions, however, specific implementations and different hardware structures may also be different. If you do not pay attention to them, errors may occur!
Iv. Summary:
From the above analysis, we can draw the following conclusions:
1. floating point numbers have errors;
2. Precision-sensitive data such as currency should be expressed or stored in a specific number of points;
3. If floating point numbers are used in programming, pay special attention to the error and try to avoid Floating Point Number comparison;
4. Handle some special floating point values.
Notes
MYSQL 5.022,
If a field f is of the float type, the SQL statement is:
Select X from T where f = 2.2;
Even if the table contains 2.2 of the data, it cannot be queried.
There are two solutions:
1. Changing float to the double type will not cause this problem. However, this method is not suitable if the data volume in the database is large or the modification volume is too large. This method is only suitable for the initial stage of database design.
2. Set the float precision and perform the query.
To be accurate to three digits, select * from T where format (f, 3) = format (2.2, 3 );
However, the precision cannot exceed 6. Otherwise, an error occurs because the float type can be precise to up to 6 digits after the decimal point.