MySQL数字运算奇怪 - 溢出?

时间:2014-07-02 20:27:59

标签: mysql sql

关于MySQL的第一个查询出了什么问题?

两列的预期答案是' 718042670591505846'

SELECT 5002622390 + (5102 * 140737488355328) new_iid_hard_way,
     CAST(5002622390 + (5102 * POWER(2,47)) AS UNSIGNED) new_iid_WRONG_way

它返回:

' 718042670591505846',' 718042670591505792'

同时,此查询有效:

SELECT 5002622390 + (5102 * 140737488355328) new_iid_hard_way,
   5002622390 + (5102 * CAST(POWER(2,47) AS UNSIGNED)) new_iid_CORRECT_way

它返回: ' 718042670591505846',' 718042670591505846'

我的预感是它是一个数据类型溢出/包装问题......但即使在MySQL 5.6.15上启用严格模式,我也不会收到任何错误。

有趣的是,在所有4种情况下,sqlfiddle都错了:

http://sqlfiddle.com/#!9/d1bb6/1

返回718042670591505800

这是溢出问题吗?如果是,那么为什么在启用严格模式时MySQL不会抛出错误?

1 个答案:

答案 0 :(得分:1)

有些操作在DECIMAL完成,有些操作在DOUBLE完成。这可以解释为什么数字在第16位有效数字之后会有所不同。

这是另一种方法:

5002622390 + (5102 << 47)

<<是二元移位,因此它与*POW(2, ...)

具有相同的效果

使用DECIMAL得到718042670591505846的正确答案:

SELECT CAST(5002622390 AS DECIMAL) + (5102 * 140737488355328);
SELECT CAST(5002622390 AS DECIMAL) + (5102 << 47)