关于MYSQL中FLOAT和DOUBLE类型的存储
发表于:2025-11-08 作者:千家信息网编辑
千家信息网最后更新 2025年11月08日,关于MYSQL中FLOAT和DOUBLE类型的存储其实在单精度和双精度浮点类型存储中其存储方式和C/C++一致准守IEEE标准他们都是浮点型的,所谓的浮点型,是小数点的位置可变,其能够表示的范围比定点
千家信息网最后更新 2025年11月08日关于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数据库重建表
服务器新硬盘黄灯常亮
南阳颈副网络技术有限公司
软件开发招聘广告语
苹果用id如何恢复数据库
2019网络安全大事件国内
数据库的自动化技术
网络安全等级保护市场
手机pc模拟器服务器
河北软件开发外包公司哪个好
服务器同时转发多台
什么是互联网金融科技
河南工业大学国泰安数据库
支付宝网络技术
网络安全建设哪里有
服务器检测版本不安全的破解
西宁软件开发培训机构
互联网金融科技公司
实体类与数据库表字段对应注解
虹口区推广软件开发供应商价位
共道科技杭州互联网法院
软件开发项目功能清单
手机pc模拟器服务器