mysql 浮点数与定点数

2019-08-25 鲁鲁槟 收藏

八、mysql 浮点数与定点数

8.1、浮点数

①、存储形式

浮点数的小数点位置是变化的,用阶码和尾数开表示,不用惧怕它的表示形式,它也是一串亲切0、1序列。

IEEE754标准从逻辑上用三元组{S,E,M}表示一个浮点数N,如下图所示:(以四字节单精度的浮点型数据为例)

01.png

其中:

  • S表示该浮点数N的符号位,0代表正,1代表负;

  • E为阶码,表示N的指数位,用一个字节表示(8位)

  • M 为尾数,表示小数部分,该部分决定了浮点型数据的有效数字或精度

下面来看一下如何将一个实数浮点型按该格式存储为二进制:

②、以3.25为例:

首先可以得到符号位S=0;

然后将3.25转化为二进制表示:11.01,进而变化为:1.101*2^1;

那么,阶码即为1+bias=1+127=128;(单精度浮点型数据的偏移量bias为127)

所以E=10000000

尾数为省去默认的小数点左边的1后剩下的数,即为:101,这也就是为什么23位的尾数可以表示24位精度的缘故。所以M=10100000000000000000000;

所以3.25的二进制存储为:0 10000000 10100000 00000000 0000000

同样,给你一个存储形式按照上边的逆过程你也可以得到他要表示的浮点型数据,这里就不多说了。好吧,还是举个例子吧:

比如:二进制形式为:1 01111010 11000000000000000000000

首先符号位为1,表示该数据为负

E=01111010,01111010转换为十进制为:122,     122-127=-5;

M=11000000000000000000000

所以该数为:1.11000000000000000000000*2^(-5)=0.0000111,后边的0可以省略了

转化为十进制:0.0546875

8.2、定点数

定点数是指小数点的位置是固定不变的,通常分为定点小数和定点整数,用之前先规定好小数点的位置,可以在符号位和数字有效位之间,也可以在数字有效位之后,运算简单,但是表示范围小,要考虑溢出,一般在DSP中有用。

8.3、MySQL中使用浮点数类型和定点数类型来表示小数

浮点数类型包括单精度浮点数(float型)和双精度浮点数(double型)。定点数类型就是decimal型。

8.4、几种数据类型的取值范围和存数的字节数

01.png

关于上表的解释:

①、Decimal型的取值范围和double相同。但是decimal的有效取值范围由M和D决定,而且Decimal型的字节数是M+2。也就是说,定点数的存储空间是根据其精度决定的。

②、MySQL中可以指定浮点数和定点数的精度。其基本形式如下:数据类型(M,D)。

其中,“数据类型”参数是浮点数或定点数的数据类型名称,M参数称为精度,是数据的总长度,小数点不占位置。D参数成为标度,是指小数点后面的长度是D。

举个例子:float(6,2)的含义数据是float型,数据长度是6,小数点后保留2位。所以,1234.56是符合要求的。

③、浮点数:上述指定的小数精度的方法虽然都适用于浮点数和定点数,但不是浮点数的标准用法。建议在定义浮点数时,如果不是实际情况需要,最好不要使用,如果使用了,可能会影响数据库的迁移。

④、定点数:decimal(M,D)是定点数的标准格式,以字符串形式存储,一般情况下可以选择这种数据类型。

⑤、指定精度:如果插入值的精度高于实际定义的精度,系统会自动进行四舍五入处理,使值的精度达到要求。

⑥、不指定精度:FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认整数为10,小数为0。

8.5、例子1

①、创建表

CREATE TABLE t(c1 FLOAT(10,2) DEFAULT NULL,c2 DECIMAL(10,2) DEFAULT NULL);

②、插入数据

往 c1,c2 中插入数据1.234

INSERT INTO t VALUES(1.234,1.234);

③、查看警告

show warnings;

01.png

小结:定点数如果数据超过了精度和标度值会报错,而浮点数不会。

④、查看表数据:

SELECT * FROM t;

01.png

数据正确插入,但是由于标度的限制,舍去了最后一位。

小结:如果插入值的精度高于实际定义的精度,系统会自动进行四舍五入处理,使值的精度达到要求。

⑤、插入数据

往 c1,c2 中插入数据 131072.32

INSERT INTO t VALUES(131072.32,131072.32);

⑥、查看表数据:

SELECT * FROM t;

01.png

我们看到c1列的值由131072.32变成了131072.31,这就是浮点数的不精确性造成的。

小结:浮点数会引起精度问题

8.6、例子2

①、创建表

CREATE TABLE t2(c1 FLOAT DEFAULT NULL,c2 DECIMAL DEFAULT NULL);

②、插入数据

往 c1,c2 中插入数据1.234

INSERT INTO t2 VALUES(1.234,1.234);

③、查看表数据:

SELECT * FROM t2;

01.png

我们看到c2列的值为1,这是因为d定点数在不指定精确度时,默认为decimal(10,0)。

小结:FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认整数为10,小数为0。

8.7、总结

  • 定点数以字符串形式存储,其精度比浮点数要高,存储空间是根据其精度决定的。

  • 浮点数的小数点位置是变化的,用阶码和尾数表示,浮点数会引起精度问题。在长度一定的情况下,浮点数能够表示更大的数据范围。

  • 对货币等对精度敏感的数据,应该用定点数表示或存储。

  • 编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较

暂时还没有评论,快来抢沙发吧~

发表评论

您需要登录后才可以评论。登录 | 立即注册
阅读 33