关于MySQL中FLOAT和DOUBLE类型的存储

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位

实际的数据是
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其额外的部分为无效数字

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

猜你喜欢

转载自www.linuxidc.com/Linux/2016-04/130338.htm