溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

關(guān)于MYSQL中FLOAT和DOUBLE類(lèi)型的存儲(chǔ)

發(fā)布時(shí)間:2020-08-10 10:43:54 來(lái)源:ITPUB博客 閱讀:158 作者:gaopengtttt 欄目:MySQL數(shù)據(jù)庫(kù)
關(guān)于MYSQL中FLOAT和DOUBLE類(lèi)型的存儲(chǔ)


其實(shí)在單精度和雙精度浮點(diǎn)類(lèi)型存儲(chǔ)中其存儲(chǔ)方式和C/C++一致準(zhǔn)守IEEE標(biāo)準(zhǔn)他們都是浮點(diǎn)型的,所謂的浮點(diǎn)型,是小數(shù)點(diǎn)的位置可變,其能夠表示的范圍比定點(diǎn)小數(shù)要廣得多,而存儲(chǔ)空間節(jié)省,但是受到精度的影響,所以在嚴(yán)格的數(shù)據(jù)中盡量使用定點(diǎn)小數(shù)mysql decimal(m,d)類(lèi)型,ORACLE壓根沒(méi)有浮點(diǎn)數(shù)字類(lèi)型而是number(p,s)定點(diǎn)小數(shù),

float 4字節(jié)
    1       8      23
  符號(hào)位   指數(shù)位 尾數(shù)

double 8字節(jié)
    1       11     52
   符號(hào)位  指數(shù)位  尾數(shù)
那么很明顯他們的精度取決于尾數(shù)。
而表示的范圍取決于指數(shù)。

float表示范圍:
2^8=(-128—127)
-2^128—2^127 
約為-3.4E38—3.4E38
double表示范圍:
2^11=(-1024—1023)
-2^1024—2^1023
約為-1.7E308—1.7E308
可以看到這個(gè)范圍實(shí)際上很廣,但是精度確很小
float精度:
float 尾數(shù)23位,2^23=8.3E6  6-7位
double尾數(shù)52位,2^52=4.5E15 14-15位

那么如果使用浮點(diǎn)數(shù)據(jù)保存了精度大于其范圍的數(shù)據(jù)其會(huì)使用四舍五入的方法截?cái)唷?br /> MYSQL如下:
mysql> create table dname(id1 float,id2 double,name varchar(20));
Query OK, 0 rows affected (0.08 sec)
mysql> insert into dname values(1234567.123,1234567.123,'gaopeng');
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dname;
+---------+-------------+---------+
| id1     | id2         | name    |
+---------+-------------+---------+
| 1234570 | 1234567.123 | gaopeng |
+---------+-------------+---------+
1 row in set (0.00 sec)
雖然進(jìn)行了四舍五入,但是不會(huì)有任何報(bào)錯(cuò)和警告,這是其標(biāo)準(zhǔn)決定的而不是數(shù)據(jù)庫(kù)本生。
可以看到1234567.123在FLOAT下被四舍五入為1234570,而DOUBLE類(lèi)型沒(méi)有問(wèn)題,那么我們
直接從數(shù)據(jù)文件中提取數(shù)據(jù)。
我還是使用了自己寫(xiě)的小工具BCVIEW
[root@hadoop1 test]# bcview dname.ibd 16 127 40
******************************************************************
This Tool Is Uesed For Find The Data In Binary format(Hexadecimal)
Usage:./bcview file blocksize offset cnt-bytes!                   
file: Is Your File Will To Find Data!                             
blocksize: Is N kb Block.Eg: 8 Is 8 Kb Blocksize(Oracle)!         
                         Eg: 16 Is 16 Kb Blocksize(Innodb)!       
offset:Is Every Block Offset Your Want Start!                                     
cnt-bytes:Is After Offset,How Bytes Your Want Gets!                               
Edtor QQ:22389860!                                                
Used gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)                
******************************************************************
----Current file size is :0.093750 Mb
----Current use set blockszie is 16 Kb
current block:00000000--Offset:00127--cnt bytes:40--data is:00ffffffff0000000000010000000200260000000200260000000000000000ffffffff0000ffffff
current block:00000001--Offset:00127--cnt bytes:40--data is:00000000000000000000000000000000000000000000000000000000000000000000000000000000
current block:00000002--Offset:00127--cnt bytes:40--data is:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
current block:00000003--Offset:00127--cnt bytes:40--data is:000001cc6d090000002d5679ab00000d0c011039b4964991ed7c1f87d6324167616f70656e670000
current block:00000004--Offset:00127--cnt bytes:40--data is:00000000000000000000000000000000000000000000000000000000000000000000000000000000
current block:00000005--Offset:00127--cnt bytes:40--data is:00000000000000000000000000000000000000000000000000000000000000000000000000000000

實(shí)際的數(shù)據(jù)是
000001cc6d09         rowid         
0000002d5679ab       事物ID          
00000d0c0110         回滾指針          
39b49649             1234570       
91ed7c1f87d63241     1234567.123   
67616f70656e67       'gaopeng'     
關(guān)于如何得到數(shù)據(jù)的可以參考我的博文
http://blog.itpub.net/7728585/viewspace-2071787/
我們來(lái)分析下float的組成,因?yàn)長(zhǎng)INUX屬于小端,存儲(chǔ)會(huì)是反向的
39b49649實(shí)際是4996b439

49 01001001
96 10010110
b4 10110100
39 00111001

   0     10010011     00101101011010000111001
符號(hào)位   指數(shù)位             尾數(shù)

10010011=147
這里需要減去127
147-127=20為指數(shù)

尾數(shù) 00101101011010000111001需要加入一個(gè)1.
如下1.00101101011010000111001
如此我們需要將1.00101101011010000111001
乘以2的20次方實(shí)際就是右移動(dòng)20位

100101101011010000111.001
整數(shù)部分
100101101011010000111=1234567這里就是最后的數(shù)據(jù)1234567
而顯示的時(shí)候1234567又被四舍五入為1234570

再來(lái)看double

91ed7c1f87d63241
實(shí)際為
4132d6871f7ced91

0                          符號(hào)位
10000010011  1043 然后1043-1023=20 級(jí)指數(shù)位 
0010110101101000011100011111011111001110110110010001

1.0010110101101000011100011111011111001110110110010001
100101101011010000111.00011111011111001110110110010001


整數(shù)部分為100101101011010000111=1234567 
關(guān)于小數(shù)部分的計(jì)算:
0*2^(0-1) 第一位
0*2^(0-2) 第二位
0*2^(0-3) 第三位
1*2^(0-4)=1/16 第四位
1*2^(0-5)=1/32 第五位
1*2^(0-6)=1/64 第六位
.....
及0.123=0.0001111101111100其額外的部分為無(wú)效數(shù)字

實(shí)際上數(shù)據(jù)是沒(méi)有問(wèn)題的。
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI