mysql 存取浮点型_关于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其额外的部分为无效数字

实际上数据是没有问题的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7728585/viewspace-2079958/,如需转载,请注明出处,否则将追究法律责任。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值