曾经负责测试BI线数据时候,遇到过一些很有意思问题。每次分析问题,查到最后都是些很基础的问题,比如浮点数类型不满足加法交换律:
double a = value1;
double b = value2;
(a + b) != (b + a)
下面分享一段做数据分析的SQL代码(代码是精简版,实际代码复杂很多):
- 有一张表结构:
列名 | 类型 |
---|---|
id | BIGINT |
price | Double |
order_id | VARCHAR |
buyer_id | VARCHAR |
case 1 提取数据的sql:
select sum(a) from test where id>1000 order by order_id;
select sum(a) from test where id>1000
以上两条sql的结果随着数据量的增加,差异会远大于可接受的误差范围。-
case 2 现在我们换个姿势再来一次:
select sum(column_a)
from (
select sum(a) as column_a from test group by buyer_id
) table1select sum(a) from test where id>1000
结果与case1一样,差异随着数据量的增加,差异会远大于可接受的误差范围。
在这两个case中,有两点需要注意:
- order by 或者 group by会改变原始数据的顺序。
- 浮点数不满足交换律
如果在应用中某个字段是涉及钱相关的敏感字段,最好乘以1000以控制误差范围。
最后分享一个面试实习生时候关于浮点数的一个题目:
请用C语言写一个程序,判断两个浮点数是否相等。
// 判断两个浮点数是否相等,相等返回true,否则返回false。
bool isEqual(double a, double b) {
if(abs(a-b) < 0.0000001) {
return true;
} else {
return false;
}
}
此程序隐藏了一个bug,(a-b)有溢出的可能。