Fixed-Point Types in MySQL You Might Not Know

Fixed-point type

It is precisely because the use of floating-point numbers to represent decimals may be inaccurate. In some cases, we must ensure that the decimals are accurate, so the uncles who designed MySQL proposed a data type called fixed-point numbers, which also stores decimals. a method:

in:

  • M represents the maximum number of decimal significant digits required for the decimal.

Note that it is the number of significant digits , for example, for a decimal**-2.3 , the number of significant digits is 2, and for a decimal 0.9 , the number of significant digits is 1**.

  • D represents the number of decimal digits after the decimal point of the decimal.

This is easy to understand, there are several decimal digits after the decimal point, what is the value of D.

For example, take a look at the change in the value range of single-precision floating-point numbers with M and D set:

It can be seen that in the case of the same D, the larger the M, the larger the value range of the type; in the case of the same M, the larger the D, the smaller the value range of the type . Of course, the values ​​of M and D are not infinite, the value range of M is 1~255 , the value range of D is 0~30 , and the value of D must not be greater than M. Both M and D are optional, and if we omit them, their values ​​are stored according to the maximum value supported by the machine.

We say that a fixed-point number is an exact decimal. In order to achieve the purpose of accuracy, we cannot convert it into a binary decimal and then store it (because there are many decimal decimals that need to be rounded after being converted to binary decimals, resulting in binary decimal representation. Numerical values ​​are imprecise). In fact, after thinking about it, the so-called decimal is just dividing two decimal integers with a decimal point. We only need to store the two decimal integers around the decimal point. Isn't that accurate. For example, for the decimal fraction 2.38 , we can save the two integers around the decimal point of the decimal, that is, 2 and 38 , respectively, then it is equivalent to saving an accurate decimal, isn't this wave of operations very important? 6.

Of course, things are not so simple. For a **DECIMAL(M, D) type given M and D values, such as DEMCIMAL(16, 4)**:

  • First, determine that the integer to the left of the decimal point needs to store up to 12 decimal digits, and the integer to the right of the decimal point needs to store 4 decimal digits, as shown in the figure:

  • Starting from the decimal point, each integer is divided into groups every 9 decimal places, and the effect is as follows:

As can be seen from the figure, if there are less than 9 decimal digits, it will also be divided into a group.

  • For the decimal numbers in each group, convert them into binary numbers for storage. Depending on the number of decimal numbers contained in the group, the required storage space is also different, as shown in the following table:

Therefore , DECIMAL(16, 4) needs to occupy a total of 8 bytes of storage space, and these 8 bytes are composed of the following three parts:

  1. Group 1 contains 3 decimal digits and requires 2 bytes of storage.
  2. Group 2 contains 9 decimal digits and requires 4 bytes of storage.
  3. Group 3 contains 4 decimal digits and requires 2 bytes of storage.
  • Set the most significant bit of the converted completed bit sequence to 1.

These steps are a bit confusing, don't worry, just give an example to make it clear. Let's say we use the fixed-point type DECIMAL(16, 4) to store the decimal fraction 1234567890.1234 , which is divided into 3 parts:

1 234567890 1234

That is:

  1. Group 1 contains the integer 1.
  2. Group 2 contains the integer 234567890.
  3. Group 3 contains the integer 1234.

Then convert the decimal numbers in each group to the corresponding binary numbers:

  • The first group occupies 2 bytes, and the binary number corresponding to the integer 1 is (there is actually no space between the bytes, but we add a space for the convenience of everyone's understanding):
00000000 00000001

Binary looks too uncomfortable, let's convert it to the corresponding hexadecimal and take a look:

0x0001
  • The second group occupies 4 bytes, and the hexadecimal number corresponding to the integer 234567890 is:
0x0DFB38D2
  • The third group occupies 2 bytes, and the hexadecimal number corresponding to the integer 1234 is:
0x04D2

So concatenating these hex numbers is:

0x00010DFB38D204D2

Finally, the highest bit of the result must be set to 1, so the final decimal fraction 1234567890.1234 occupies a total of 8 bytes when stored using the fixed-point type **DECIMAL(16, 4)**, the specific content is:

0x80010DFB38D204D2

Some friends will ask, what if we want to use the fixed-point type DECIMAL(16, 4) to store a negative number, for example -1234567890.1234 , then we only need to perform an inversion operation for each bit in 0x80010DFB38D204D2 , that is, the following result is obtained:

0x7FFEF204C72DFB2D

From the above description, we can know that for the DECIMAL(M, D) type, the given values ​​of M and D are different, and the required storage space is also different. It can be seen that fixed-point numbers require more space to store data than floating-point numbers, so if it is not in some scenarios where precise decimals need to be stored, floating-point numbers are sufficient for general decimals.

For the fixed-point type DECIMAL(M, D) , both M and D are optional, the default value of M is 10, and the default value of D is 0, which means that the following equation is true:

DECIMAL = DECIMAL(10) = DECIMAL(10, 0)
DECIMAL(n) = DECIMAL(n, 0)

In addition , the range of M is 1~65 , the range of D is 0~30 , and the value of D cannot exceed M.

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324193697&siteId=291194637