转载

[mysql基础文档]-8-数据类型之浮点数

在储存数据的过程中,经常会遇到一些小数,比如某些商品的价格,这个时候就可以用到本文介绍的浮点数类型了。

文章目录

  • [1].单精度浮点数
  • [2].双精度浮点数
  • [3].如何使用decimal类型储存小数

[1].单精度浮点数

单精度浮点数的声明语法是float(M,D),使用4字节储存数据,其中M表示浮点数允许的最大长度(小数点前和小数点后的总长度),D表示小数点后精确的位数。

假设声明float(4,2),代表总长度是4的小数,小数点后能储存2位,多出的尾数四舍五入,小数点前能储存4-2=2位,超出会让整个数字变成4位小数能够储存的最大值,即99.99。

请看下面的实例:

//新建表t5,仅包含一列fl,单精度浮点型,允许最大长度4,精确到小数点后2位显示 mysql> create table t5(fl float(4,2));  //插入一个3位小数 mysql> insert into t5 values(1.23);  //插入一个4位小数,但小数点后有3位 mysql> insert into t5 values(1.236);  //插入一个5位小数,小数点后有3位 mysql> insert into t5 values(12.236);  //插入一个4位小数,小数点前有3位,此时报错 mysql> insert into t5 values(123.2); Query OK, 1 row affected, 1 warning (0.01 sec)  //结果分析,第一条语句完全没有问题,第二条记录因为设定了只允许精确到小数点后2位,所以四舍五入了,第三条语句同样被四舍五入了,相信看到这里,最大的疑问就是为什么最后一条记录,长度是4位,并没有超过限制,插入后却显示了99.99,实际上,float在声明的过程中有一个规定,如果声明了小数点后精确2位,小数后不论有没有2位,都占用两个名额,也就意味着,小数点前面最大长度只能是2位,因为总长度只能是4位,尽管本例中小数点后只有一位数字。 //理解这一点后,就不难判断,当小数点前面出现3位的时候,实际上加上小数点后的两个名额(不管有没有)都已经是5位的长度,所以整个小数被设定成4位小数能够储存的最大值99.99 mysql> select * from t5; +-------+ | fl    | +-------+ |  1.23 | |  1.24 | | 12.24 | | 99.99 | +-------+

P.s:单精度浮点数使用4个字节存储数据,如果声明单精度浮点数的时候不声明范围(不包含括号和括号中的参数),那么默认的储存范围是-3.402823466E+38到-1.175494351E-38、0和1.175494351E-38到3.402823466E+38。

[2].双精度浮点数

双精度浮点数声明语句是double(M,D),使用8个字节存储数据,使用方法和单精度是完全一样的,唯一不同的是,如果声明双精度浮点数时不声明范围,那么默认允许的范围是-1.7976931348623157E+308到-2.2250738585072014E-308、0和2.2250738585072014E-308到 1.7976931348623157E+308。

这里不再赘述双精度浮点数的使用方法,请参考单精度浮点数的实例部分,将float替换成double即可。

[3].如何使用decimal类型储存小数

不论使用单精度还是双精度储存浮点数,都不可避免的存在精度损失,为了避免精度损失,最好的做法就是使用decimal类型,decimal类型声明语法Decimal(M,D),同单精度浮点数一样,M声明可存放的小数总长度,D声明小数点后可以精确多少位。

Decimal类型精度范围为 1 到 31;

存储Decimal数据需要的字节数计算公式:精度/2(舍掉小数)+ 1 ;例如decimal(9,4),所占用的字节为9/2=4.5,直接去掉小数得4,再用4+1=5字节。如果没有为decimal列定义提供精度和小数位值,那么缺省情况下,使用精度值 5 和小数位值 0(因此,需要 3 个字节的存储空间)。

单精度浮点数精度损失问题实例:

//新建表t6,设定两列,第一列float类型,第二列decimal类型,两列支持的最大长度都设定成9,小数点后支持两位 mysql> create table t6(fl float(9,2),de decimal(9,2));  //输入数值测试,数值本身并没有超过规定的长度 mysql> insert into t6 values(1234567.89,1234567.89);  //float类型末尾出现精度损失,而decimal因为采取了压缩十进制格式存储,所以更加精确 mysql> select * from t6; +------------+------------+ | fl         | de         | +------------+------------+ | 1234567.88 | 1234567.89 | +------------+------------+

P.s:对储存较大的浮点数时,建议使用decimal类型储存,至于为什么浮点数的储存会损失精度,请参考计算机原理基础书籍。

[**] 注:如文中未特别声明转载请注明出自:QingSword.COM

正文到此结束
Loading...