处理小数
,你可以把整数看成小数的一个特例。因此,浮点数和定点数的使用场景,比整数大多了。 MySQL支持的浮点数类型,分别是 FLOAT、DOUBLE、REAL
。FLOAT
表示单精度浮点数;DOUBLE
表示双精度浮点数;REAL
默认就是 DOUBLE
。如果把 SQL 模式设定为启用“REAL_AS_FLOAT
”,那 么,MySQL 就认为 REAL
是 FLOAT
。如果要启用“REAL_AS_FLOAT
”,可以通过以下 SQL 语句实现: SET sql_mode = “REAL_AS_FLOAT”;
问题1: FLOAT 和 DOUBLE 这两种数据类型的区别是什么?
FLOAT
占用字节数少,取值范围小;DOUBLE
占用字节数多,取值范围也大。
问题2: 为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于有符号数取值范围大于等于零的部分呢?
MySQL 存储浮点数的格式为:符号(S)
、尾数(M)
和 阶码(E)
。因此,无论有没有符号,MySQL 的浮点数都会存储表示符号的部分。因此, 所谓的无符号数取值范围,其实就是有符号数取值范围大于等于零的部分。
对于浮点类型,在MySQL中单精度值使用4
个字节,双精度值使用8
个字节。
非标准语法
(其他数据库未必支持,因此如果涉及到数据迁移,则最好不要这么用):FLOAT(M,D)
或DOUBLE(M,D)
。这里,M称为精度
,D称为标度
。(M,D)中 M=整数位+小数位,D=小数位。 D<=M<=255,0<=D<=30。 例如,定义为FLOAT(5,2)
的一个列可以显示为-999.99-999.99
。如果超过这个范围会报错。
UNSIGNED
,但是不会改变数据范围,例如:FLOAT(3,2) UNSIGNED
仍然只能表示0-9.99
的范围。- 若四舍五入后,整数部分没有超出范围,则只警告,但能成功操作并四舍五入删除多余的小数位后保存。例如在FLOAT(5,2)列内插入999.009,近似结果是999.01。
- 若四舍五入后,整数部分超出范围,则MySQL报错,并拒绝处理。如FLOAT(5,2)列内插入999.995和-999.995都会报错。
FLOAT
和DOUBLE
的UNSIGNED
也不推荐使用了,将来也可能被移除。CREATE TABLE test_double1(
f1 FLOAT,
f2 FLOAT(5,2),
f3 DOUBLE,
f4 DOUBLE(5,2)
);
DESC test_double1;
INSERT INTO test_double1(f1, f2)
VALUES(123.45,123.45);
SELECT * FROM test_double1;
INSERT INTO test_double1(f3,f4)
VALUES(123.45,123.456); #存在四舍五入
f4(5,2)
,可以得知 整数位:3
,小数位:2
,1234.456
超出整数位的访问了INSERT INTO test_double1(f3,f4)
VALUES(123.45,1234.456);
浮点数类型有个缺陷,就是不精准。下面我来重点解释一下为什么 MySQL 的浮点数不够精准。比如,我们设计一个表,有f1
这个字段,插入值分别为0.47,0.44,0.19
,我们期待的运行结果是:0.47 + 0.44 + 0.19 = 1.1
。而使用sum
之后查询:
CREATE TABLE test_double2(
f1 DOUBLE
);
INSERT INTO test_double2
VALUES(0.47),(0.44),(0.19);
mysql> SELECT SUM(f1)
-> FROM test_double2;
+--------------------+
| SUM(f1) |
+--------------------+
| 1.0999999999999999 |
+--------------------+
1 row in set (0.00 sec)
mysql> SELECT SUM(f1) = 1.1,1.1 = 1.1
-> FROM test_double2;
+---------------+-----------+
| SUM(f1) = 1.1 | 1.1 = 1.1 |
+---------------+-----------+
| 0 | 1 |
+---------------+-----------+
1 row in set (0.00 sec)
1.0999999999999999
。看到了吗?虽然误差很小,但确实有误差。 你也可以尝试把数据类型改成 FLOAT
,然后运行求和查询,得到的是, 1.0999999940395355。显然,误差更大了。DECIMAL
。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。