關於MYSQL中FLOAT和DOUBLE型別的儲存
關於MYSQL中FLOAT和DOUBLE型別的儲存
其實在單精度和雙精度浮點型別儲存中其儲存方式和C/C++一致準守IEEE標準他們都是浮點型的,所謂的浮點型,是小數點的位置可變,其能夠表示的範圍比定點小數要廣得多,而儲存空間節省,但是受到精度的影響,所以在嚴格的資料中儘量使用定點小數mysql decimal(m,d)型別,ORACLE壓根沒有浮點數字型別而是number(p,s)定點小數,
float 4位元組
1 8 23
符號位 指數位 尾數
double 8位元組
1 11 52
符號位 指數位 尾數
那麼很明顯他們的精度取決於尾數。
而表示的範圍取決於指數。
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
可以看到這個範圍實際上很廣,但是精度確很小
float精度:
float 尾數23位,2^23=8.3E6 6-7位
double尾數52位,2^52=4.5E15 14-15位
那麼如果使用浮點資料儲存了精度大於其範圍的資料其會使用四捨五入的方法截斷。
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)
雖然進行了四捨五入,但是不會有任何報錯和警告,這是其標準決定的而不是資料庫本生。
可以看到1234567.123在FLOAT下被四捨五入為1234570,而DOUBLE型別沒有問題,那麼我們
直接從資料檔案中提取資料。
我還是使用了自己寫的小工具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
實際的資料是
000001cc6d09 rowid
0000002d5679ab 事物ID
00000d0c0110 回滾指標
39b49649 1234570
91ed7c1f87d63241 1234567.123
67616f70656e67 'gaopeng'
關於如何得到資料的可以參考我的博文
http://blog.itpub.net/7728585/viewspace-2071787/
我們來分析下float的組成,因為LINUX屬於小端,儲存會是反向的
39b49649實際是4996b439
49 01001001
96 10010110
b4 10110100
39 00111001
0 10010011 00101101011010000111001
符號位 指數位 尾數
10010011=147
這裡需要減去127
147-127=20為指數
尾數 00101101011010000111001需要加入一個1.
如下1.00101101011010000111001
如此我們需要將1.00101101011010000111001
乘以2的20次方實際就是右移動20位
為
100101101011010000111.001
整數部分
100101101011010000111=1234567這裡就是最後的資料1234567
而顯示的時候1234567又被四捨五入為1234570
再來看double
91ed7c1f87d63241
實際為
4132d6871f7ced91
0 符號位
10000010011 1043 然後1043-1023=20 級指數位
0010110101101000011100011111011111001110110110010001
為
1.0010110101101000011100011111011111001110110110010001
100101101011010000111.00011111011111001110110110010001
整數部分為100101101011010000111=1234567
關於小數部分的計算:
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其額外的部分為無效數字
實際上資料是沒有問題的。
其實在單精度和雙精度浮點型別儲存中其儲存方式和C/C++一致準守IEEE標準他們都是浮點型的,所謂的浮點型,是小數點的位置可變,其能夠表示的範圍比定點小數要廣得多,而儲存空間節省,但是受到精度的影響,所以在嚴格的資料中儘量使用定點小數mysql decimal(m,d)型別,ORACLE壓根沒有浮點數字型別而是number(p,s)定點小數,
float 4位元組
1 8 23
符號位 指數位 尾數
double 8位元組
1 11 52
符號位 指數位 尾數
那麼很明顯他們的精度取決於尾數。
而表示的範圍取決於指數。
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
可以看到這個範圍實際上很廣,但是精度確很小
float精度:
float 尾數23位,2^23=8.3E6 6-7位
double尾數52位,2^52=4.5E15 14-15位
那麼如果使用浮點資料儲存了精度大於其範圍的資料其會使用四捨五入的方法截斷。
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)
雖然進行了四捨五入,但是不會有任何報錯和警告,這是其標準決定的而不是資料庫本生。
可以看到1234567.123在FLOAT下被四捨五入為1234570,而DOUBLE型別沒有問題,那麼我們
直接從資料檔案中提取資料。
我還是使用了自己寫的小工具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
實際的資料是
000001cc6d09 rowid
0000002d5679ab 事物ID
00000d0c0110 回滾指標
39b49649 1234570
91ed7c1f87d63241 1234567.123
67616f70656e67 'gaopeng'
關於如何得到資料的可以參考我的博文
http://blog.itpub.net/7728585/viewspace-2071787/
我們來分析下float的組成,因為LINUX屬於小端,儲存會是反向的
39b49649實際是4996b439
49 01001001
96 10010110
b4 10110100
39 00111001
0 10010011 00101101011010000111001
符號位 指數位 尾數
10010011=147
這裡需要減去127
147-127=20為指數
尾數 00101101011010000111001需要加入一個1.
如下1.00101101011010000111001
如此我們需要將1.00101101011010000111001
乘以2的20次方實際就是右移動20位
為
100101101011010000111.001
整數部分
100101101011010000111=1234567這裡就是最後的資料1234567
而顯示的時候1234567又被四捨五入為1234570
再來看double
91ed7c1f87d63241
實際為
4132d6871f7ced91
0 符號位
10000010011 1043 然後1043-1023=20 級指數位
0010110101101000011100011111011111001110110110010001
為
1.0010110101101000011100011111011111001110110110010001
100101101011010000111.00011111011111001110110110010001
整數部分為100101101011010000111=1234567
關於小數部分的計算:
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其額外的部分為無效數字
實際上資料是沒有問題的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2079958/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- java double、float型別的比較Java型別
- double型別資料在記憶體中中儲存格式型別記憶體
- float和double有什麼區別?
- decimal,float和double的區別是什麼?Decimal
- c語言中%f輸出double型和float型值C語言
- 【PL/SQL】IEEE浮點型別BINARY_FLOAT和BINARY_DOUBLESQL型別
- C語言中關於float、double、long double精度及數值範圍理解C語言
- C#引用型別和值型別在堆、棧中的儲存C#型別
- MYSQL 資料型別儲存-數值型MySQL 資料型別
- MySQL 中 整數型別的儲存和範圍計算過程詳解MySql型別
- 關於 Go 中 Map 型別和 Slice 型別的傳遞Go型別
- JavaScript中的資料型別-儲存差別JavaScript資料型別
- mysql儲存日期使用什麼型別MySql型別
- MYSQL-資料型別儲存-DATEMySql資料型別
- 關於java中的double check lockJava
- 開發中遇到的float double精度問題
- 【MySQL】時間型別儲存格式選擇MySql型別
- 關於mysql中欄位定義的型別int、tinyint區別MySql型別
- 如何檢視mysql中表的儲存引擎型別薦MySql儲存引擎型別
- Oracle 儲存型別Oracle型別
- MySQL儲存引擎:MyISAM和InnoDB的區別MySql儲存引擎
- sql server資料庫如何儲存陣列,int[]float[]double[]陣列儲存到資料庫方法SQLServer資料庫陣列
- 在SQL Server中儲存和輸出任意型別的檔案SQLServer型別
- 建立NFS型別的儲存NFS型別
- int float double 各型別的最大值最小值型別
- mysql儲存函過程和儲存函式都屬於儲存程式MySql儲存函式
- Golang的值型別和引用型別的範圍、儲存區域、區別Golang型別
- 字元型別的字元儲存與位元組儲存字元型別
- C/C++——求下面資料型別的最大值和最小值: char, short, int, long, float, double, long double和numeric_limits使用C++資料型別MIT
- PLSQL Language Reference-針對BINARY_FLOAT和BINARY_DOUBLE的額外PL/SQL子型別SQL型別
- 準確詳解:C/C++ float、double資料型別的表示範圍及精度C++資料型別
- Java深海拾遺系列(5)--- 精度計算中的BigDecimal,double和floatJavaDecimal
- 關於hibernate 和 儲存過程儲存過程
- 隨筆:MySQL中'' ' ' NULL在Innodb儲存的區別MySqlNull
- Mysql 的儲存過程和儲存函式MySql儲存過程儲存函式
- mysql和orcale的儲存過程和儲存函式MySql儲存過程儲存函式
- Float型別*100的坑 (BigDecimal 的使用)和float形的格式化型別Decimal
- 深圳Java培訓:Java中的float在記憶體中的儲存Java記憶體