疑问案例:
查询员工表中薪水的减免税超过0.2(20%)的数据:
select name, salary, deductions from employees where deductions > 0.2;
查询结果:
John 100000.0 0.2
Mary 80000.0 0.2
Tom 200000.0 0.3
Fred 150000.0 0.3
为什么deductions = 0.2 的记录也被输出了?
原因:
浮点数float和double在比较的过程中,存在float转化为double进行比较的过程,在float --> double中会出现0.2的最近似的精确值略大于0.2的情况。
这个问题并非仅仅存在于Hive中,Java也存在此问题。
这是所有使用IEEE标准进行浮点数编码的系统中,普遍存在的一个问题。
0.2对于float 类型是0.2000001,而对于double类型是0.200000000001。
这是因为一个8字节的double值具有更多的小数位(小数点后的位数)。当表中的float值通过Hive转换为double值时,其产生的double值是0.200000100000,这个值实际要比0.200000000001大,这就是为什么查询结果像是使用了 >= 而不是 > 了。
对于上述问题的规避方法:
使用cast操作符显式地指出0.2是float类型。
cast语法:cast( 数值 as float )
select name, salary, deductions from employees where deductions > cast(0.2 as float);