关于MYSQL中FLOAT和DOUBLE类型的存储
发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,关于MYSQL中FLOAT和DOUBLE类型的存储其实在单精度和双精度浮点类型存储中其存储方式和C/C++一致准守IEEE标准他们都是浮点型的,所谓的浮点型,是小数点的位置可变,其能够表示的范围比定点
千家信息网最后更新 2025年01月31日关于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其额外的部分为无效数字
实际上数据是没有问题的。
数据
尾数
实际
精度
范围
类型
存储
小数
浮点
四舍五入
数位
符号
四舍
定点
取决于
字节
实际上
就是
指数
数字
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
sql数据库管理教学视频
通信软件开发是做什么
软件开发服务类别
EDI是网络安全技术吗
河北数据库培训学费
无线桥接dns服务器没有响应
网络技术和新媒体
网吧主副服务器切换
中学生网络安全电子报
云服务器 网络安全
服务器安全软件破解版下载
自学软件开发c
高清服务器西瓜视频教程
涉密网络安全保密讲座
四层数据库前端应用层
山西百旺税控服务器管理系统
云服务器 永久
信阳直播软件开发方案
网络安全基线配置标准
数据库查询的自身连接查询
图书馆数据库以下查询例题
中孚科技网络安全
阿里云能用作代理服务器吗
数据网络安全泄漏新闻报道
论文常用的电子数据库
c语言软件开发方案
进入微信显示服务器无响应
科技互联网佛山市
数据库多大内存
软件开发工资多少